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 的链接或提交表单
  • JavaScript 调用 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 字符串
  • frameName 字符串(可选)
  • features 字符串(可选)

返回 Window | null

🌐 Returns Window | null

features 是一个逗号分隔的键值列表,遵循浏览器的标准格式。Electron 会尽可能地从该列表中解析 BrowserWindowConstructorOptions ,以便使用。若想获得更全面的控制和更好的使用体验,可以考虑使用 webContents.setWindowOpenHandler 来自定义 BrowserWindow 的创建。

WebPreferences 的一个子集可以直接从特性字符串中设置,且无需嵌套:zoomFactornodeIntegrationjavascriptcontextIsolationwebviewTag

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

例如:

🌐 For example:

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

注意:

  • 如果父窗口中禁用了 Node 集成,则在打开的 window 中 Node 集成将始终被禁用。
  • 如果父窗口启用了上下文隔离,则在打开的 window 中上下文隔离也将始终启用。
  • 如果父窗口中禁用了 JavaScript,那么在打开的 window 中 JavaScript 也将始终被禁用。
  • features 中提供的非标准功能(Chromium 或 Electron 未处理的)将传递给任何已注册的 webContentsdid-create-window 事件处理程序,作为 options 参数。
  • frameName 遵循位于 本地文档target 规范。
  • 在打开 about:blank 时,子窗口的 WebPreferences 会从父窗口复制过来,并且无法覆盖它,因为在这种情况下 Chromium 会跳过浏览器端的导航。

要自定义或取消窗口的创建,你可以选择在主进程中使用 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.

除了传入 actionoverrideBrowserWindowOptionsoutlivesOpener 可以这样传入:{ 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>')