contextBridge
分離されたコンテキスト間に、安全、双方向で同期されたブリッジを作成します
プロセス: Renderer
分離されたプリロードスクリプトから API をレンダラーに公開する例を以下に示します。
// プリロード (隔離ワールド)
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
// レンダラー (メインワールド)
window.electron.doThing()
用語集
メインワールド
"メインワールド" は、メインレンダラーコードが実行される JavaScript コンテキストです。 デフォルトでは、レンダラーでロードしたページはこのワールドでコードを実行します。
隔離ワールド
webPreferences
で contextIsolation
が有効 (これは Electron 12.0.0 からの既定の動作) になっている場合、preload
スクリプトは "隔離ワールド" で実行されます。 コンテキスト分離とその影響の詳細については、BrowserWindow のドキュメントを参照してください。
メソッド
contextBridge
モジュールには以下のメソッドがあります。
contextBridge.exposeInMainWorld(apiKey, api)
apiKey
string -window
に API を注入するキー。 その API にはwindow[apiKey]
でアクセスできます。api
Record - あなたの API です。この詳細と動作については下記を参照してください。
contextBridge.exposeInIsolatedWorld(worldId, apiKey, api)
worldId
Integer - API を注入するワールドの ID です。0
はデフォルトのワールドで、999
は Electron のcontextIsolation
機能で使用されるワールドです。 999 を使用すると、プリロードコンテキストのオブジェクトが公開されます。 隔離ワールドを作成する際には 1000 以上の使用を推奨します。apiKey
string -window
に API を注入するキー。 その API にはwindow[apiKey]
でアクセスできます。api
Record - あなたの API です。この詳細と動作については下記を参照してください。
使い方
API
exposeInMainWorld
に指定する api
は、Function
、string
、number
、Array
、boolean
、または文字列のキーで Function
、string
、number
、Array
、boolean
、同じ条件を満たすオブジェクトのいずれかの値の、入れ子でなければなりません。
Function
値は他のコンテキストへプロキシされ、他のすべての値は コピー か 凍結 されます。 API で送信されるデータ/プリミティブはイミュータブルであり、ブリッジの一方で更新しても他方のものは更新されません。
複雑な API の例を以下に示します。
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing'),
myPromises: [Promise.resolve(), Promise.reject(new Error('whoops'))],
anAsyncFunction: async () => 123,
data: {
myFlags: ['a', 'b', 'c'],
bootTime: 1234
},
nestedAPI: {
evenDeeper: {
youCanDoThisAsMuchAsYouWant: {
fn: () => ({
returnData: 123
})
}
}
}
}
)
exposeInIsolatedWorld
の例を以下に示します。
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInIsolatedWorld(
1004,
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
// レンダラー (ワールド ID 1004 で隔離されています)
window.electron.doThing()
API 関数
contextBridge
を介してバインドした Function
値は、コンテキストが分離されたままになるように Electron を介してプロキシされます。 これにより、以下に概説するいくつかの重要な制限が生じます。
引数 / エラー / 戻り値型のサポート
引数、エラー、戻り値は、ブリッジを介して送信されるときに コピー されるため、使用できるのは特定の型のみです。 高水準なものは、使用したい型をシリアライズおよびデシリアライズして、同じように動作するオブジェクトにできます。 以下の型サポートの表に全てが載っています。
種類 | 複雑さ | 引数サポート | 戻り値サポート | 制限事項 |
---|---|---|---|---|
文字列型 | 単純 | ✅ | ✅ | なし |
number | 単純 | ✅ | ✅ | なし |
boolean | 単純 | ✅ | ✅ | なし |
Object | 複雑 | ✅ | ✅ | キーにはこの表の "単純" な型のみの使用をサポートしています。 値にはこの表のものをサポートしています。 プロトタイプの変更は削除されます。 カスタムクラスを送信すると、値はコピーされますが、プロトタイプはコピーされません。 |
Array | 複雑 | ✅ | ✅ | 制限は Object 型と同じです |
エラー | 複雑 | ✅ | ✅ | 送出された Error もコピーされるため、異なるコンテキストで投げられたためにエラーのメッセージやスタックトレースが少し変化することがあります。また、Error オブジェクトのカスタムプロパティは 失われます。 |
Promise | 複雑 | ✅ | ✅ | なし |
Function | 複雑 | ✅ | ✅ | プロトタイプの変更は削除されます。 クラスまたはコンストラクターを送信しても動作しません。 |
複製可能型 | 単純 | ✅ | ✅ | 複製可能型に関してはリンクのドキュメントを参照してください |
Element | 複雑 | ✅ | ✅ | プロトタイプの変更は削除されます。 カスタム要素の送信は動作しません。 |
Blob | 複雑 | ✅ | ✅ | なし |
Symbol | なし | ❌ | ❌ | Symbol はコンテキスト間でコピーできないため、削除されます |
関心のある型が上記の表にない場合、それはおそらくサポートされていません。
Node のグローバルシンボルの公開
contextBridge
はプリロードスクリプトで使用でき、レンダラーが Node API へアクセスできるようにします。 上記のサポート型の表は、 contextBridge
を介して公開する Node API にも適用されます。 注意として、Node API の多くはローカルシステムのリソースへのアクセスを許してしまいます。 信頼できない外部コンテンツにおいては、公開するグローバルや API について注意が必要です。
const { contextBridge } = require('electron')
const crypto = require('crypto')
contextBridge.exposeInMainWorld('nodeCrypto', {
sha256sum (data) {
const hash = crypto.createHash('sha256')
hash.update(data)
return hash.digest('hex')
}
})