跳转到主要内容

从渲染器打开窗口

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

  • 点击带有 target=_blank 的链接或提交表单
  • JavaScript 调用 window.open()

对于同源内容,新窗口将在同一进程中创建,允许父窗口直接访问子窗口。这对于用作首选项面板等的应用子窗口非常有用,因为父窗口可以直接渲染到子窗口,就像父窗口中的一个 div 一样。这与浏览器中的行为相同。

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

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

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

  • url string
  • frameName 字符串 (可选)
  • features 字符串 (可选)

返回 Window | null

features 是一个逗号分隔的键值对列表,遵循浏览器的标准格式。Electron 会尽力从列表中解析出 BrowserWindowConstructorOptions 以方便使用。为了获得完全控制和更好的可用性,请考虑使用 webContents.setWindowOpenHandler 来自定义 BrowserWindow 的创建。

可以通过 features 字符串直接设置一部分 WebPreferences,而无需嵌套:zoomFactornodeIntegrationjavascriptcontextIsolationwebviewTag

例如

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。请注意,这比通过 features 字符串传递选项更强大,因为渲染器在决定安全偏好方面比主进程拥有更有限的权限。

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

原生 Window 示例

// 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>')