メインコンテンツへ飛ぶ

レンダラーからウインドウを開く

レンダラー内での信頼されたもしくは信頼されていないコンテンツからのウインドウ作成を制御する方法がいくつかあります。 ウインドウはレンダラーから以下の 2 つの方法で作成できます。

  • target=_blank が付加された、リンクのクリックやフォームの送信
  • JavaScript での window.open() 呼び出し

同一オリジンコンテンツの場合、新しいウインドウは同じプロセス内で作成され、親が子ウィンドウに直接アクセスできるようになります。 これは、アプリのサブウインドウが環境設定パネルなどとして機能する場合に非常に便利です。親はサブウインドウに対して、あたかも親が持つ div のように直接レンダリングできます。 これはブラウザと同じ動作です。

Electron は、このネイティブの Chrome Window と BrowserWindow をペアリングします。 レンダラーで作成されたウインドウに対して webContents.setWindowOpenHandler() を使用することで、メインプロセスでの BrowserWindow 作成と同じすべてのカスタマイズを活用できます。

BrowserWindow constructor options are set by, in increasing precedence order: parsed options from the features string from window.open(), security-related webPreferences inherited from the parent, and options given by webContents.setWindowOpenHandler. 注意として、webContents.setWindowOpenHandler はメインプロセスで呼び出されるため、最終的な決定権と完全なアクセス権限があります。

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

  • url string
  • frameName string (任意)
  • features string (任意)

戻り値 Window | null

features は、ブラウザの標準フォーマットに従ったカンマ区切りのキーバリューリストです。 Electron will parse BrowserWindowConstructorOptions out of this list where possible, for convenience. 完全な制御とより良い人間工学を実現するため、webContents.setWindowOpenHandler で BrowserWindow の作成をカスタマイズするようにご検討ください。

A subset of WebPreferences can be set directly, unnested, from the features string: zoomFactor, nodeIntegration, preload, javascript, contextIsolation, and webviewTag.

以下がその例です。

window.open('https://github.com', '_blank', 'top=500,left=200,frame=false,nodeIntegration=no')

注釈:

  • Node integration は、親ウィンドウで無効になっている場合は、開いた window でも常に無効になります。
  • コンテキストイソレーションは、親ウィンドウで有効になっている場合は、開いた window で常に有効になります。
  • JavaScript は、親ウィンドウで無効になっている場合は、開いた window でも常に無効になります。
  • features で指定された非標準機能 (Chromium や Electron によって処理されない) は、options 引数内の登録された webContentsdid-create-window イベントハンドラに渡されます。
  • frameName は、ネイティブのドキュメント にある target の仕様に従います。
  • When opening about:blank, the child window's WebPreferences will be copied from the parent window, and there is no way to override it because Chromium skips browser side navigation in this case.

ウインドウの作成をカスタマイズまたはキャンセルするにあたって、メインプロセスから webContents.setWindowOpenHandler() でオーバーライドハンドラーを任意設定できます。 { action: 'deny' } を返すと、ウィンドウはキャンセルされます。 { action: 'allow', overrideBrowserWindowOptions: { ... } } を返すと、ウインドウを開くことと、ウィンドウ作成時に使用する BrowserWindowConstructorOptions の設定を許可します。 これは、feature 文字列でオプションを渡すよりも強力であることに注意してください。レンダラーは、セキュリティ設定を決定する権限がメインプロセスよりも制限されているからです。

actionoverrideBrowserWindowOptions に加えて、outlivesOpener を次のように渡すことができます。{ action: 'allow', outlivesOpener: true, overrideBrowserWindowOptions: { ... } }true に設定すると、これを開いたウインドウが閉じても、新しく作成されたウィンドウは閉じません。 デフォルト値はfalseです。

ネイティブの Window のサンプル

// main.js
const mainWindow = new BrowserWindow()

// この例では、URL が `about:blank` であるウインドウのみが作成されます。
// ほかのすべての 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' }
})
// レンダラープロセス (mainWindow)
const childWindow = window.open('', 'modal')
childWindow.document.write('<h1>Hello</h1>')