1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/wallace5303-electron-egg

 / Детали:

Изоляция контекста делает использование ipcRenderer напрямую из preload/bridge.js бессмысленным.

Предстоит сделать
Владелец
Создано  
12.03.2025

После тестирования в официальном демо при установке contextIsolation как true в конфигурационном файле config.default.js, а также активации preload: path.join(appInfo.baseDir, 'preload', 'bridge.js'), возникли ошибки при вызове метода removeAllListeners в файле ./frontend/src/utils/ipcRenderer.js. После сравнения поведения с включенными и отключенными режимами контекста было установлено, что официальная документация Electron не рекомендует прямое использование ipcRenderer при включённой изоляции контекста. В действительности, это ограничение уже встроено внутрь системы.

Мой файл bridge.js был модифицирован следующим образом, чтобы успешно воспроизвести поведение ipcRenderer без изоляции контекста:

const { contextBridge, ipcRenderer } = require('electron');

// Пример передачи данных через bridge
contextBridge.exposeInMainWorld('ipcRenderer', {
    send(channel, data) {
        ipcRenderer.send(channel, data);
    },
    on(channel, func) {
        const handler = (event) => func(event);
        ipcRenderer.on(channel, handler);
        return () => {
            ipcRenderer.removeListener(channel, handler);
        };
    },
    removeAllListeners() {
        ipcRenderer.removeAllListeners();
    }
});
```Этот код позволяет безопасно использовать `ipcRenderer` даже при включенном режиме изоляции контекста.

```javascript
const { contextBridge, ipcRenderer } = require('electron');

/**
 * Официальная документация ipc: https://www.electronjs.org/ru/docs/latest/api/ipc-renderer
 *
 * Свойства/Методы
 * ipc.on(channel, listener) - Отслеживает channel, когда приходит новое сообщение, вызывает listener (альтернативное имя для ipcRenderer.addListener)
 * ipc.once(channel, listener) - Добавляет одноразовый listener
 * ipc.off(channel, listener) - Удаляет конкретный listener для определенного channel из очереди слушателей (альтернативное имя для ipcRenderer.removeListener)
 * ipc.removeAllListeners(channel) - Удаляет все слушатели, если указан channel, то удаляются только те, что связаны с ним
 * ipc.send(channel, ...args) - Отправляет асинхронное сообщение через channel в основной процесс
 * ipc.invoke(channel, param) - Отправляет асинхронное сообщение (модель invoke/handle)
 * Нечасто используемые методы
 * ipc.postMessage(channel, message, [transfer]) - Отправляет сообщение в основной процесс
 * ipc.sendSync(channel, param) - Отправляет синхронное сообщение (модель send/on), использование не рекомендуется
 * ipc.sendToHost(channel, ...args) - Сообщение отправляется в элемент <webview> на странице host
 * Устаревшие методы
 * ipc.sendTo(webContentsId, channel, ...args) - Отправляет сообщение через channel в окно с webContentsId
 *
 * Отправка сообщений от основного процесса в процесс рендера (три способа)
 * При использовании on, параметр event предоставляет event.reply и event.sender.
 */
```отправить, первый отправляет ответ обратно отправителю (может быть частью страницы), второй отправляет сообщение в процесс
  * При использовании handle, можно вернуть значение через async, например ipcMain. handle("isTablePC", async (event, data) => { return isTabletPC });
  * Также можно использовать метод webContents. send основного процесса для отправки сообщений
  *
  * Электрон-эгг фреймворк по умолчанию поддерживает каналы с названием контроллер. файл. метод, так как они уже прослушиваются в ee-core/socket/ipcServer. js!
  */
 ``````javascript
 // const { on, off, once, removeAllListeners, send, invoke, postMessage, sendToHost, sendTo } = ipcRenderer;```javascript
contextBridge.exposeInMainWorld('electron', {
   // Ошибка 1: Электрон официально не рекомендует прямое использование ipcRenderer, поэтому использование ipcRenderer в приложении может вызывать проблемы с некоторыми методами
   // ipcRenderer,
   // Ошибка 2: Хотелось распаковать и переопределить методы, но это привело к тому, что некоторые методы работали некорректно, например window.electron.ipcRenderer.on не работает как ожидалось
   // ipcRenderer:{on, off, once, removeAllListeners, send, invoke, postMessage, sendToHost, sendTo},//Хотелось использовать деконструкцию
   // Корректное решение: каждый метод должен быть переопределен отдельно, чтобы они корректно работали в контексте рендера
   ipcRenderer: {
      on: (channel, listener) => ipcRenderer.on(channel, listener),//Подписаться на событие
      once: (channel, listener) => ipcRenderer.once(channel, listener),//Подписаться на событие один раз
      off: (channel, listener) => ipcRenderer.removeListener(channel, listener),//Отписаться от события
      removeAllListeners: (channel) => ipcRenderer.removeAllListeners(channel),//Удалить все подписки на канал
      send: (channel, ...args) => ipcRenderer.send(channel, ...args),//Отправить сообщение (асинхронно)
      // sendSync: (channel, params) => ipcRenderer.sendSync(channel, params),//Отправить сообщение (синхронно), Электрон официально считает этот способ устаревшим и не рекомендует его
      invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args),//Вызвать асинхронную функцию (через Promise), Электрон рекомендует этот способ
      postMessage: (channel, message, [transfer]) => ipcRenderer.postMessage(channel, message, [transfer]),//Отправить сообщение в основной процесс
      sendToHost: (channel, ...args) => ipcRenderer.sendToHost(channel, ...

Пожалуйста, обратите внимание, что последняя строка была оборвана и требует завершения.```javascript
args), //Аналогично send, отличие в том, что отправляет сообщение в webview элемент хоста
sendTo: (webContentsId, channel, ...args) => ipcRenderer.sendTo(webContentsId, channel, ...args), //Отправить сообщение в указанный контент
},
});

Комментарий (0)

GitLife Service Account Задача создана

Вход Перед тем как оставить комментарий

Статус
Ответственный
Контрольная точка
Pull Requests
Связанные запросы на слияние могут быть закрыты после их объединения
Ветки
Дата начала   -   Крайний срок
-
Закрепить/Открепить
Приоритет
Участники(1)
1
https://api.gitlife.ru/oschina-mirror/wallace5303-electron-egg.git
git@api.gitlife.ru:oschina-mirror/wallace5303-electron-egg.git
oschina-mirror
wallace5303-electron-egg
wallace5303-electron-egg