contextBridge

Create a safe, bi-directional, synchronous bridge across isolated contexts

进程: 渲染进程

An example of exposing an API to a renderer from an isolated preload script is given below:

  1. // Preload (Isolated World)
  2. const { contextBridge, ipcRenderer } = require('electron')
  3. contextBridge.exposeInMainWorld(
  4. 'electron',
  5. {
  6. doThing: () => ipcRenderer.send('do-a-thing')
  7. }
  8. )
  1. // Renderer (Main World)
  2. window.electron.doThing()

词汇表

Main World

The “Main World” is the JavaScript context that your main renderer code runs in. By default, the page you load in your renderer executes code in this world.

Isolated World

When contextIsolation is enabled in your webPreferences, your preload scripts run in an “Isolated World”. You can read more about context isolation and what it affects in the security docs.

方法

The contextBridge module has the following methods:

contextBridge.exposeInMainWorld(apiKey, api) Experimental

  • apiKey String - The key to inject the API onto window with. The API will be accessible on window[apiKey].
  • api any - Your API, more information on what this API can be and how it works is available below.

用法

API

The api provided to exposeInMainWorld must be a Function, String, Number, Array, Boolean, or an object whose keys are strings and values are a Function, String, Number, Array, Boolean, or another nested object that meets the same conditions.

Function values are proxied to the other context and all other values are copied and frozen. Any data / primitives sent in the API become immutable and updates on either side of the bridge do not result in an update on the other side.

An example of a complex API is shown below:

  1. const { contextBridge } = require('electron')
  2. contextBridge.exposeInMainWorld(
  3. 'electron',
  4. {
  5. doThing: () => ipcRenderer.send('do-a-thing'),
  6. myPromises: [Promise.resolve(), Promise.reject(new Error('whoops'))],
  7. anAsyncFunction: async () => 123,
  8. data: {
  9. myFlags: ['a', 'b', 'c'],
  10. bootTime: 1234
  11. },
  12. nestedAPI: {
  13. evenDeeper: {
  14. youCanDoThisAsMuchAsYouWant: {
  15. fn: () => ({
  16. returnData: 123
  17. })
  18. }
  19. }
  20. }
  21. }
  22. )

API Functions

Function values that you bind through the contextBridge are proxied through Electron to ensure that contexts remain isolated. This results in some key limitations that we’ve outlined below.

Parameter / Error / Return Type support

Because parameters, errors and return values are copied when they are sent over the bridge, there are only certain types that can be used. At a high level, if the type you want to use can be serialized and deserialized into the same object it will work. A table of type support has been included below for completeness:

类型ComplexityParameter SupportReturn Value Support局限性
字符串SimpleN/A
NumberSimpleN/A
BooleanSimpleN/A
Object - 过滤器对象,包含过滤参数ComplexKeys must be supported using only “Simple” types in this table. Values must be supported in this table. Prototype modifications are dropped. Sending custom classes will copy values but not the prototype.
ArrayComplexSame limitations as the Object type
ErrorComplexErrors that are thrown are also copied, this can result in the message and stack trace of the error changing slightly due to being thrown in a different context
PromiseComplexPromises are only proxied if they are the return value or exact parameter. Promises nested in arrays or objects will be dropped.
Function - 回调函数ComplexPrototype modifications are dropped. Sending classes or constructors will not work.
Cloneable TypesSimpleSee the linked document on cloneable types
SymbolN/ASymbols cannot be copied across contexts so they are dropped

If the type you care about is not in the above table, it is probably not supported.