Skip to main content

contextBridge

Создает безопасный, двунаправленный, синхронный мост через изолированные контексты

Процесс: Графический

Пример предоставления API-интерфейса средству визуализации из изолированного сценария предварительной загрузки приведен ниже:

// Предварительная загрузка (Isolated World/Изолированный Мир)
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
// Рендер (Main World/Основной Мир)

window.electron.doThing()

Глоссарий

Main World / Основной Мир

"Main World" - это контекст javascript, в котором запускается ваш основной код рендера. По умолчанию загружаемая вами страница выполняет код в этом контексте.

Isolated World / Изолированный Мир

Когда contextIsolation включен в вашем webPreferences (Это стандартное поведение в Electron 12.0.0) ваши preload скрипты выполняются в "Isolated World". Вы можете прочитать больше о контекстной изоляции и на что это влияет в документации BrowserWindow.

Методы

Модуль contextBridge имеет следующие методы:

contextBridge.exposeInMainWorld(apiKey, api)

  • apiKey String - Ключ для вставки API в window. API будет доступен в window[apiKey].
  • api Record - Ваш объект API, более подробная информация о том, что это и как он будет работать, доступна ниже.

Usage

API

Объект api, предоставленный для exposeInMainWorld, должен быть объектом, ключи которого являются строками, а значения являются 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
})
}
}
}
}
)

Функции API

Значения Function, которые вы связываете через contextBridge, передаются через Electron, чтобы гарантировать, что контексты остаются изолированными. Это приводит к некоторым ключевым ограничениям, которые мы описали ниже.

Параметр / Ошибка / Поддержка возвращаемого типа

Поскольку параметры, ошибки и возвращаемые значения скопированы при отправке через мост, существуют только определенные типы, которые могут быть использованы. На высоком уровне, если тип, который вы хотите использовать, может быть сериализован и десериализован в один и тот же объект, то он будет работать. A table of type support has been included below for completeness:

ТипСложностьПоддержка параметровВозврат значения поддержкиОграничения
StringПростойНет
NumberПростойНет
BooleanПростойНет
ObjectСложныйКлючи должны поддерживаться «Простыми» типами в этой таблице. Значения должны поддерживаться в этой таблице. Модификации прототипа отбрасываются. Отправка пользовательских классов будет копировать значения, но не прототип.
ArrayСложныйТе же ограничения, что и в типе Object
ErrorСложныйОшибки, которые выбрасываются также копируются, это может привести к тому, что сообщение и трассировка стека ошибки немного изменятся из-за того, что они будут выброшены в другом контексте
PromiseСложныйПромисы передаются только если они являются возвращаемым значением или точным параметром. Промисы, вложенные в массивы или объекты, будут удалены.
FunctionСложныйМодификации прототипа отбрасываются. Отправка классов или конструкторов не будет работать.
Cloneable TypesПростойСмотрите связанный документ по клонируемым типам
ElementСложныйМодификации прототипа отбрасываются. Отправка пользовательских элементов не будет работать.
BlobСложныйНет
SymbolНетСимволы не могут быть скопированы в разных контекстах, поэтому они отбрасываются

Если тип, о котором вы хотите использовать, не находится в приведенной выше таблице, то он, вероятно, не поддерживается.

Exposing Node Global Symbols

contextBridge может использоваться скриптом preload для предоставления вашему устройству доступа к узлам API. Таблица поддерживаемых типов, описанная выше, также применяется к Node API, которые вы используете через contextBridge. Пожалуйста, обратите внимание, что многие 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')
}
})