從渲染器開啟視窗
有多種方法可以控制如何從渲染器中受信任或不受信任的內容建立視窗。可以透過兩種方式從渲染器建立視窗
- 點擊連結或提交帶有
target=_blank
裝飾的表單 - JavaScript 呼叫
window.open()
對於同源內容,新視窗會在相同的程序中建立,使父視窗可以直接存取子視窗。這對於作為偏好設定面板或類似功能的應用程式子視窗非常有用,因為父視窗可以直接渲染到子視窗,就像它是父視窗中的 div
一樣。這與瀏覽器中的行為相同。
Electron 在底層將這個原生 Chrome Window
與 BrowserWindow 配對。您可以利用在主程序中建立 BrowserWindow 時可用的所有自訂功能,方法是對渲染器建立的視窗使用 webContents.setWindowOpenHandler()
。
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 整合,則在開啟的
視窗
中將始終停用 Node 整合。 - 如果父視窗啟用了內容隔離,則在開啟的
視窗
中將始終啟用內容隔離。 - 如果父視窗停用了 JavaScript,則在開啟的
視窗
中將始終停用 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>')