从渲染器打开窗口
有几种方法可以控制如何从渲染器中受信任或不受信任的内容创建窗口。可以通过两种方式从渲染器创建窗口
- 点击带有
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
字符串frameName
字符串(可选)features
字符串(可选)
返回 Window
| null
features
是一个逗号分隔的键值列表,遵循浏览器的标准格式。为了方便起见,Electron 将尽可能从此列表中解析 BrowserWindowConstructorOptions
。为了实现完全控制和更好的工程设计,请考虑使用 webContents.setWindowOpenHandler
自定义 BrowserWindow 的创建。
可以从 features 字符串直接设置 WebPreferences
的一个子集,无需嵌套:zoomFactor
、nodeIntegration
、preload
、javascript
、contextIsolation
和 webviewTag
。
例如
window.open('https://github.com', '_blank', 'top=500,left=200,frame=false,nodeIntegration=no')
注意
- 如果在父窗口中禁用 Node 集成,则在打开的
window
中将始终禁用 Node 集成。 - 如果在父窗口中启用上下文隔离,则在打开的
window
中将始终启用上下文隔离。 - 如果在父窗口中禁用 JavaScript,则在打开的
window
中将始终禁用 JavaScript。 - 在
features
中给出的非标准功能(Chromium 或 Electron 未处理的功能)将传递给任何已注册的webContents
的did-create-window
事件处理程序中的options
参数。 frameName
遵循位于 原生文档中的target
的规范。- 打开
about:blank
时,子窗口的WebPreferences
将从父窗口复制,并且在这种情况下无法覆盖它,因为 Chromium 会跳过浏览器端导航。
要自定义或取消窗口的创建,您可以选择从主进程使用 webContents.setWindowOpenHandler()
设置一个重写处理程序。返回 { action: 'deny' }
将取消窗口。返回 { action: 'allow', overrideBrowserWindowOptions: { ... } }
将允许打开窗口,并将 BrowserWindowConstructorOptions
设置为创建窗口时使用。请注意,这比通过 feature 字符串传递选项更强大,因为在决定安全偏好方面,渲染器的权限比主进程更有限。
除了传入 action
和 overrideBrowserWindowOptions
,还可以像这样传入 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>')