首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用contextIsolation = true,可以使用ipcRenderer吗?

使用contextIsolation = true,可以使用ipcRenderer吗?
EN

Stack Overflow用户
提问于 2019-03-14 13:56:11
回答 3查看 12.3K关注 0票数 16

这是我的装置:

步骤1.使用以下代码创建一个preload.js文件:

代码语言:javascript
复制
window.ipcRenderer = require('electron').ipcRenderer;

步骤2.通过main.js通过webPreferences预加载该文件:

代码语言:javascript
复制
  mainWindow = new BrowserWindow({
    width: 800, 
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      preload: __dirname + '/preload.js'
    }
  });

步骤3.在渲染器中:

代码语言:javascript
复制
console.log(window.ipcRenderer); // Works!

现在按照电子的安全指南,我想转一下contextIsolation=truehttps://electronjs.org/docs/tutorial/security#3-enable-context-isolation-for-remote-content

步骤2之二。

代码语言:javascript
复制
  mainWindow = new BrowserWindow({
    width: 800, 
    height: 600,
    webPreferences: {
      contextIsolation: true,
      nodeIntegration: false,
      preload: __dirname + '/preload.js'
    }
  });

步骤3之二。在渲染器中:

console.log(window.ipcRenderer); // undefined

问题:我可以在ipcRenderer时使用contextIsolation=true吗?

EN

回答 3

Stack Overflow用户

发布于 2020-01-10 03:21:45

2022编辑

对于那些希望了解IPC呈现器的人,我已经发布了一个帖子,它解释了这个概念,以及与使用IPC呈现器相关的安全问题。

新答案

您可以遵循设置在此概述。这个设置实际上是在secure-electron-template中使用的,您可以这样做:

main.js

代码语言:javascript
复制
const {
  app,
  BrowserWindow,
  ipcMain
} = require("electron");
const path = require("path");
const fs = require("fs");

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win;

async function createWindow() {

  // Create the browser window.
  win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false, // is default value after Electron v5
      contextIsolation: true, // protect against prototype pollution
      enableRemoteModule: false, // turn off remote
      preload: path.join(__dirname, "preload.js") // use a preload script
    }
  });

  // Load app
  win.loadFile(path.join(__dirname, "dist/index.html"));

  // rest of code..
}

app.on("ready", createWindow);

ipcMain.on("toMain", (event, args) => {
  fs.readFile("path/to/file", (error, data) => {
    // Do something with file contents

    // Send result back to renderer process
    win.webContents.send("fromMain", responseObj);
  });
});

preload.js

代码语言:javascript
复制
const {
    contextBridge,
    ipcRenderer
} = require("electron");

// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld(
    "api", {
        send: (channel, data) => {
            // whitelist channels
            let validChannels = ["toMain"];
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, data);
            }
        },
        receive: (channel, func) => {
            let validChannels = ["fromMain"];
            if (validChannels.includes(channel)) {
                // Deliberately strip event as it includes `sender` 
                ipcRenderer.on(channel, (event, ...args) => func(...args));
            }
        }
    }
);

index.html

代码语言:javascript
复制
<!doctype html>
<html lang="en-US">
<head>
    <meta charset="utf-8"/>
    <title>Title</title>
</head>
<body>
    <script>
        window.api.receive("fromMain", (data) => {
            console.log(`Received ${data} from main process`);
        });
        window.api.send("toMain", "some data");
    </script>
</body>
</html>

原创

您仍然能够在呈现程序进程中使用ipcRenderer,并将contextIsolation设置为true。contextBridge是您想要使用的,尽管有一个当前臭虫阻止您在呈现程序进程中调用ipcRenderer.on;您所能做的就是将呈现程序进程发送到主进程。

这段代码取自安全电子模板,这是一种为电子构建的模板,它考虑到了安全性。(我是作者)

preload.js

代码语言:javascript
复制
const { contextBridge, ipcRenderer } = require("electron");

contextBridge.exposeInMainWorld(
    "electron",
    {
        ipcRenderer: ipcRenderer
    }
);

main.js

代码语言:javascript
复制
let win;

async function createWindow() {

  // Create the browser window.
  win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      nodeIntegrationInWorker: false,
      nodeIntegrationInSubFrames: false,
      contextIsolation: true,
      enableRemoteModule: false,
      preload: path.join(__dirname, "preload.js")
    }
  });
}

某些renderer.js文件

window.electron.ipcRenderer

票数 28
EN

Stack Overflow用户

发布于 2019-03-16 01:54:02

注意上下文隔离描述中间的这个句子。很容易错过。

电子API只在preload脚本中可用,而不是在加载的页面中。

看来答案是否定的。

票数 1
EN

Stack Overflow用户

发布于 2020-07-29 18:26:55

请查一下。对我来说很管用。我用的是CRA和电子。

preload.js

代码语言:javascript
复制
    const { contextBridge, ipcRenderer } = require('electron');
    const MESSAGE_TYPES = ipcRenderer.sendSync('GET_MESSAGE_TYPES');
    
    require = null;
    
    class SafeIpcRenderer { ... }
    
    const registerMessages = () => {
      const safeIpcRenderer = new SafeIpcRenderer(Object.values(MESSAGE_TYPES));
    
      contextBridge.exposeInMainWorld('ELECTRON', {
        sendMessage: safeIpcRenderer.send,
        onReceiveMessage: safeIpcRenderer.on,
        MESSAGE_TYPES,
      });
    };
    
    registerMessages();

main.js

代码语言:javascript
复制
    const registerPreloadImports = require('./src/client/preloadUtils');
    
    // Required if sandbox flag is set to true. Non-electron modules cannot be directly imported in preload script.
    // For more info please check https://www.electronjs.org/docs/api/sandbox-option
    registerPreloadImports();
    
    let mainWindow = new BrowserWindow({
      // Web preferences for mainWindow
      webPreferences: {
        preload: path.join(__dirname, 'src/client/preload.js'),
        contextIsolation: true, // TODO: Remove it once it's enabled by default (from Electron v12)
        disableBlinkFeatures: 'Auxclick',
        sandbox: true,
        // https://www.electronjs.org/docs/api/sandbox-option#status
        enableRemoteModule: false,
      },
    });

preloadUtils.js

代码语言:javascript
复制
    const { ipcMain } = require('electron');
    const MESSAGE_TYPES = require('../utils/messageTypes');
    
    const registerPreloadImports = () => {
      ipcMain.on(MESSAGE_TYPES.GET_MESSAGE_TYPES, (event, message) => {
        event.returnValue = MESSAGE_TYPES;
      });
    };
    
    module.exports = registerPreloadImports;

messageTypes.js

代码语言:javascript
复制
    module.exports = {
      DNS_ONLINE_STATUS: 'dns-online-status',
      APP_ONLINE_STATUS: 'online-status',
      ONLINE_MODEL_SYNC: 'online-model-sync',
      APP_ONLINE: 'app-online',
      INITIAL_DATA_SYNC: 'INITIAL_DATA_SYNC',
      GET_MESSAGE_TYPES: 'GET_MESSAGE_TYPES',
    };

actions.js (渲染器)

代码语言:javascript
复制
    const { MESSAGE_TYPES, sendMessage } = window.ELECTRON || {};
    
    if (!MESSAGE_TYPES) return;
    
    const actions = {
      [MESSAGE_TYPES.INITIAL_DATA_SYNC]: (event, initialSync) => {
        console.log(MESSAGE_TYPES.INITIAL_DATA_SYNC, initialSync);
      },
    
      [MESSAGE_TYPES.ONLINE_MODEL_SYNC]: (event, message) => {
        console.log(MESSAGE_TYPES.ONLINE_MODEL_SYNC, message);
      },
    
      [MESSAGE_TYPES.APP_ONLINE]: (event, isOnline) => {
        console.log(MESSAGE_TYPES.APP_ONLINE, isOnline);
      },
    };
    
    const registerActions = () => {
      const { onReceiveMessage } = window.ELECTRON;
    
      Object.keys(actions).forEach((messageType) => {
        onReceiveMessage(messageType, actions[messageType]);
      });
    };
    
    registerActions();

package.json

代码语言:javascript
复制
    {
      "dependencies": {
        "cross-env": "7.0.2",
        "deepmerge": "4.2.2",
        "electron-is-dev": "1.2.0",
        "electron-log": "4.2.2",
        "electron-updater": "4.3.1",
        "sequelize-cli": "6.2.0",
        "sequelize": "6.3.3",
        "sqlite3": "5.0.0",
        "umzug": "2.3.0",
        "uuid": "8.2.0"
      },
      "devDependencies": {
        "concurrently": "5.2.0",
        "electron": "9.1.0",
        "electron-builder": "22.7.0",
        "spectron": "11.1.0",
        "wait-on": "5.1.0",
        "xvfb-maybe": "0.2.1"
      }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55164360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档