Spec-Zone.ru › Electron

contextBridge

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

Процесс: Рендеринг

Ниже приведён пример экспонирования API для рендера из изолированного скрипта предварительной загрузки:

// Preload (Isolated World)
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld(
  'electron',
  {
    doThing: () => ipcRenderer.send('do-a-thing')
  }
)
// Renderer (Main World)

window.electron.doThing()

Глоссарий​

Основной мир​

«Основной мир» — это контекст JavaScript, в котором выполняется код основного кода рендеринга. По умолчанию код страницы, загруженной в вашем рендере, выполняется в этом мире.

Изолированный мир​

Когда contextIsolation включён в вашем webPreferences (это стандартное поведение с Electron 12.0.0), ваши скрипты preload выполняются в «Изолированном мире». Подробнее об изоляции контекстов и её последствиях можно узнать в документации по безопасности.

Методы​

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

contextBridge.exposeInMainWorld(apiKey, api)​

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

Использование​

API​

API, предоставленное exposeInMainWorld, должно быть 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
          })
        }
      }
    }
  }
)

Функции API​

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

Поддержка параметров/ошибок/типов возвращаемых значений​

Поскольку параметры, ошибки и значения возвращаемых данных копируются при передаче через мост, существуют лишь определённые типы, которые могут быть использованы. В общих чертах, если тип, который вы хотите использовать, может быть сериализован и десериализован в тот же объект, он будет работать. Для полноты ниже приведена таблица поддержки типов:

Тип Сложность Поддержка параметров Поддержка возвращаемых значений Ограничения
string Простой ✅ ✅ Нет
number Простой ✅ ✅ Нет
boolean Простой ✅ ✅ Нет
Object Сложный ✅ ✅ Ключи должны поддерживаться, используя только «Простые» типы в этой таблице. Значения должны поддерживаться в этой таблице. Изменения прототипа отбрасываются. Отправка пользовательских классов скопирует значения, но не прототип.
Array Сложный ✅ ✅ Те же ограничения, что и для типа Object
Error Сложный ✅ ✅ Выбрасываемые ошибки также копируются, что может привести к незначительному изменению сообщения и трассировки стека ошибки из-за её выбрасывания в другом контексте, а любые пользовательские свойства объекта Error будут потеряны
Promise Сложный ✅ ✅ Нет
Function Сложный ✅ ✅ Изменения прототипа отбрасываются. Отправка классов или конструкторов не сработает.
Клонируемые типы Простой ✅ ✅ См. связанный документ по клонируемым типам
Element Сложный ✅ ✅ Изменения прототипа отбрасываются. Отправка пользовательских элементов не сработает.
Blob Сложный ✅ ✅ Нет
Symbol Нет ❌ ❌ Символы не могут быть скопированы между контекстами, поэтому они отбрасываются

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

Экспонирование глобальных символов Node​

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

© GitHub Inc.
Licensed under the MIT license.
https://www.electronjs.org/docs/latest/api/context-bridge

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API