從渲染器開啟視窗
有多種方法可以控制如何從渲染器中受信任或不受信任的內容建立視窗。視窗可以透過兩種方式從渲染器建立
- 點擊帶有
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
。請注意,這比透過功能字串傳遞選項更強大,因為渲染器在決定安全偏好設定方面的權限比主進程更有限。
除了傳入 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>')