从渲染进程打开窗口
有几种方法可以控制从信任或在渲染器内创建窗口的方式。 可以通过两种方式从渲染进程创建窗口:
- 如果属性中包含
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
stringframeName
string(可选)features
string(可选)
返回 Window | null
features
是一个逗号分割的 key-value 列表,遵循浏览器的标准格式。 方便起见,Electron 将尽可能的在列表内解析 BrowserWindowConstructorOptions
选项。 为了完全控制和更好的工效,考虑使用 webContents.setWindowOpenHandler
来自定义 BrowserWindow 的创建。
WebPreferences
的子集可以直接设置, 无需从 features 字段嵌套:zoomFactor
,nodeIntegration
,preload
,javascript
,contextIsolation
和 webviewTag
。
例如:
window.open('https://github.com', '_blank', 'top=500,left=200,frame=false,nodeIntegration=no')
说明:
- 如果在父窗口中禁用了 Node integration, 则在打开的
window
中将始终被禁用。 - 如果在父窗口中启用了上下文隔离, 则在打开的
window
中将始终被启用。 - 父窗口禁用 Javascript,打开的
window
中将被始终禁用 - 非标准功能 (不由 Chromium 或 Electron 提供) 给定
features
将传递给注册webContents
的did-create-window
事件处理函数的options
参数。 frameName
遵循于 原生文档 中windowName
的规定。- 当打开
about:blank
时,子窗口的WebPreferences
将从父窗口拷贝,因为 Chromium 会忽略浏览器侧导航,所以没有办法覆盖它。
想要自定义或取消窗口的创建, 可以选择在主进程中使用 webContents.setWindowOpenHandler()
设置替代操作。 返回 { action: 'deny' }
取消窗口。 返回 { action: 'allow', overrideBrowserWindowOptions: { ... } }
将允许打开窗口,同时当创建窗口时设置 BrowserWindowConstructorOptions
。 注意,这将比通过 feature 字段传入选项更强大,在安全方面的决定,渲染进程相比主进程有更多的限制。
除了传入 action
和 overrideBrowserWindowOptions
, outlivesOpener
,可传入类似数据:{ action: 'allow', outlivesOpener: true, overrideBrowserWindowOptions: { ... } }
。 如果设置为 true
,当打开此窗口的 opener 窗口关闭,新创建的窗口不会被关闭。 默认值为 false
。
原生 Window
示例
// main.js
const mainWindow = new BrowserWindow()
// 在此示例中,将仅创建具有 `about:blank` url 的窗口。
// 其他 url 将被阻止。
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' }
})
// 渲染进程 (主窗口)
const childWindow = window.open('', 'modal')
childWindow.document.write('<h1>Hello</h1>')