Skip to main content

从渲染器打开窗口

¥Opening windows from the renderer

有多种方法可以控制如何从渲染器中的受信任或不受信任的内容创建窗口。可以通过两种方式从渲染器创建窗口:

¥There are several ways to control how windows are created from trusted or untrusted content within a renderer. Windows can be created from the renderer in two ways:

  • 单击链接或提交带有 target=_blank 的表格

    ¥clicking on links or submitting forms adorned with target=_blank

  • JavaScript 调用 window.open()

    ¥JavaScript calling window.open()

对于同源内容,新窗口是在同一进程内创建的,使父窗口可以直接访问子窗口。这对于充当首选项面板或类似面板的应用子窗口非常有用,因为父窗口可以直接渲染到子窗口,就好像它是父窗口中的 div 一样。这与浏览器中的行为相同。

¥For same-origin content, the new window is created within the same process, enabling the parent to access the child window directly. This can be very useful for app sub-windows that act as preference panels, or similar, as the parent can render to the sub-window directly, as if it were a div in the parent. This is the same behavior as in the browser.

Electron 将原生 Chrome Window 与底层的 BrowserWindow 配对。通过对渲染器创建的窗口使用 webContents.setWindowOpenHandler(),你可以在主进程中创建 BrowserWindow 时利用所有可用的自定义。

¥Electron pairs this native Chrome Window with a BrowserWindow under the hood. You can take advantage of all the customization available when creating a BrowserWindow in the main process by using webContents.setWindowOpenHandler() for renderer-created windows.

BrowserWindow 构造函数选项按优先级递增的顺序设置:从 window.open()features 字符串解析的选项、从父级继承的与安全相关的 webPreferences 以及 webContents.setWindowOpenHandler 给出的选项。请注意,webContents.setWindowOpenHandler 拥有最终决定权和完全权限,因为它是在主进程中调用的。

¥BrowserWindow constructor options are set by, in increasing precedence order: parsed options from the features string from window.open(), security-related webPreferences inherited from the parent, and options given by webContents.setWindowOpenHandler. Note that webContents.setWindowOpenHandler has final say and full privilege because it is invoked in the main process.

window.open(url[, frameName][, features])

  • url 字符串

    ¥url string

  • frameName 字符串(可选)

    ¥frameName string (optional)

  • features 字符串(可选)

    ¥features string (optional)

返回 Window | 无效的

¥Returns Window | null

features 是一个以逗号分隔的键值列表,遵循浏览器的标准格式。为了方便起见,Electron 会尽可能从该列表中解析 BrowserWindowConstructorOptions。为了完全控制和更好的人机工程学,请考虑使用 webContents.setWindowOpenHandler 自定义 BrowserWindow 创建。

¥features is a comma-separated key-value list, following the standard format of the browser. Electron will parse BrowserWindowConstructorOptions out of this list where possible, for convenience. For full control and better ergonomics, consider using webContents.setWindowOpenHandler to customize the BrowserWindow creation.

WebPreferences 的子集可以直接从特性字符串中设置,不嵌套:zoomFactornodeIntegrationpreloadjavascriptcontextIsolationwebviewTag

¥A subset of WebPreferences can be set directly, unnested, from the features string: zoomFactor, nodeIntegration, preload, javascript, contextIsolation, and webviewTag.

例如:

¥For example:

window.open('https://github.com', '_blank', 'top=500,left=200,frame=false,nodeIntegration=no')

注意:

¥Notes:

  • 如果在父窗口上禁用节点集成,则在打开的 window 中将始终禁用节点集成。

    ¥Node integration will always be disabled in the opened window if it is disabled on the parent window.

  • 如果在父窗口上启用了上下文隔离,则在打开的 window 中将始终启用上下文隔离。

    ¥Context isolation will always be enabled in the opened window if it is enabled on the parent window.

  • 如果在父窗口上禁用 JavaScript,则在打开的 window 中 JavaScript 将始终被禁用。

    ¥JavaScript will always be disabled in the opened window if it is disabled on the parent window.

  • features 中给出的非标准功能(不由 Chromium 或 Electron 处理)将传递到 options 参数中任何已注册的 webContentsdid-create-window 事件处理程序。

    ¥Non-standard features (that are not handled by Chromium or Electron) given in features will be passed to any registered webContents's did-create-window event handler in the options argument.

  • frameName 遵循 原生文档target 的规范。

    ¥frameName follows the specification of target located in the native documentation.

  • 当打开 about:blank 时,子窗口的 WebPreferences 将从父窗口复制,并且无法覆盖它,因为在这种情况下 Chromium 会跳过浏览器端导航。

    ¥When opening about:blank, the child window's WebPreferences will be copied from the parent window, and there is no way to override it because Chromium skips browser side navigation in this case.

要自定义或取消窗口的创建,你可以选择从主进程中使用 webContents.setWindowOpenHandler() 设置覆盖处理程序。返回 { action: 'deny' } 会取消窗口。返回 { action: 'allow', overrideBrowserWindowOptions: { ... } } 将允许打开窗口并设置创建窗口时要使用的 BrowserWindowConstructorOptions。请注意,这比通过功能字符串传递选项更强大,因为渲染器在决定安全首选项方面比主进程具有更有限的权限。

¥To customize or cancel the creation of the window, you can optionally set an override handler with webContents.setWindowOpenHandler() from the main process. Returning { action: 'deny' } cancels the window. Returning { action: 'allow', overrideBrowserWindowOptions: { ... } } will allow opening the window and setting the BrowserWindowConstructorOptions to be used when creating the window. Note that this is more powerful than passing options through the feature string, as the renderer has more limited privileges in deciding security preferences than the main process.

除了传递 actionoverrideBrowserWindowOptions 之外,还可以传递 outlivesOpener,如下所示:{ action: 'allow', outlivesOpener: true, overrideBrowserWindowOptions: { ... } }。如果设置为 true,则打开器窗口关闭时新创建的窗口不会关闭。默认值为 false

¥In addition to passing in action and overrideBrowserWindowOptions, outlivesOpener can be passed like: { action: 'allow', outlivesOpener: true, overrideBrowserWindowOptions: { ... } }. If set to true, the newly created window will not close when the opener window closes. The default value is false.

原生 Window 示例

¥Native Window example

// main.js
const mainWindow = new BrowserWindow()

// In this example, only windows with the `about:blank` url will be created.
// All other urls will be blocked.
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
if (url === 'about:blank') {
return {
action: 'allow',
overrideBrowserWindowOptions: {
frame: false,
fullscreenable: false,
backgroundColor: 'black',
webPreferences: {
preload: 'my-child-window-preload-script.js'
}
}
}
}
return { action: 'deny' }
})
// renderer process (mainWindow)
const childWindow = window.open('', 'modal')
childWindow.document.write('<h1>Hello</h1>')