电子IPC和节点集成 [英] Electron IPC and nodeIntegration

查看:93
本文介绍了电子IPC和节点集成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我遵循了许多指南来设置Webpack,Electron和React来制作桌面应用程序。完成设置后,我开始工作,并了解到我需要从主机和渲染器获得IPC机制才能进行通信。

So, I've followed a number of guides to set up Webpack, Electron, and React to make a desktop application. After finishing the setup, I got to work, and learned that I needed to require an IPC mechanism from the main and renderer in order to communicate.

从 electron中导入{ipcRenderer};
将此添加到我的renderer.js文件中会导致错误 Uncaught ReferenceError:require未定义

将问题带给一些同事之后,建议我在main.js文件中进行更改

After taking my problem to some colleagues, it was suggested that in my main.js file I should change

webPreferences: {
    nodeIntegration: false,
}

webPreferences: {
    nodeIntegration: true,
}

我在Google上阅读过的每个地方都非常清楚地表明,如果您关心安全性,这就是不是您应该做的事情。但是,我为电子ipc能够使用的所有资源都使用了ipcRenderer。

Everywhere I've read on google has said very clearly that if safety is something you care about, this is not something you should do. However, every resource I've been able to come across for electron ipc has used the ipcRenderer.

现在,互联网上的每个示例是否都存在巨大的安全漏洞,或者我在这里缺少一些关键部分吗?

Now, does every example on the internet have huge security flaws, or am I missing some key part here?

我的问题如下。


  1. 可以在不启用nodeIntegration的情况下使用ipcRenderer吗?

  2. 如果是,我该怎么办?为什么这么多资源会排除此信息?

  3. 如果不是,我该怎么用?

如果我问错了问题,或者错过了一些事情,或者我问这个问题的方式还有其他明显的问题,请让我知道,否则,谢谢。

If I'm asking the wrong question, or I missed something, or there are any other clear problems with the way I've asked this question please let me know, otherwise thanks in advance.

推荐答案



  1. 是否可以在不启用nodeIntegration的情况下使用ipcRenderer?


有可能,但是很奇怪。可以使用 preload 脚本来完成。

It is possible, but fiddly. It can be done by using a preload script.



  1. 如果是,该怎么办?为什么这么多资源会排除此信息?


可以使用 preload 脚本,如下所示。但是,这是不被认为是安全的 。现有的大多数文档都没有显示最佳的安全实践。

It is possible, using the preload script as indicated below. However, this is not considered secure. Most of the existing documentation does not show best security practices.

随后给出一个更安全的示例。

A more secure example is given afterwards.

// preload.js
const electron = require('electron');

process.once('loaded', () => {
  global.ipcRenderer = electron.ipcRenderer;
});


// main.js
const {app, BrowserWindow} = require('electron');

app.on('ready', () => {
  // Create the browser window.
  win = new BrowserWindow({
      backgroundColor: '#fff', // always set a bg color to enable font antialiasing!
      webPreferences: {
        preload: path.join(__dirname, './preload.js'),
        nodeIntegration: false,
        enableRemoteModule: false,
        // contextIsolation: true,
        // nativeWindowOpen: true,
        // sandbox: true,
      }
  });
  win.loadURL(`file://${path.join(__dirname, 'index.html')}`);

注意,预加载脚本的路径必须是绝对路径,并且在使用webpack / babel时,
也可能变得复杂,因为输出文件可能有所不同

NOTE That the path to the preload script must be absolute and this can also get complicated when using webpack/babel, as the output file may be a different path.



  1. 如果不是,我该怎么用?


编辑
正如@Yannic指出的那样,El现在支持另一种选择ectron,称为 contextBridge 。此新选项可以更简单地解决问题。有关 contextBridge 的信息,请查看电子文档: https://www.electronjs.org/docs/tutorial/context-isolation

Edit As @Yannic pointed out, there is now another option supported by Electron, called contextBridge. This new option may solve the problem more simply. For info on contextBridge, check the electron docs: https://www.electronjs.org/docs/tutorial/context-isolation

如上所述,尽管可以将ipcRenderer用作如上所示,当前的电子安全建议还建议启用 contextIsolation 。这将使上述方法无法使用,因为您无法再将数据添加到全局范围。

As mentioned, although it is possible to use ipcRenderer as shown above, the current electron security recommendations recommend also enabling contextIsolation. This will make the above approach unusable as you can no longer add data to the global scope.

最安全的建议是AFAIK使用 addEventListener postMessage 代替,并使用preload脚本作为渲染器和主要脚本之间的桥梁。

The most secure recommendation, AFAIK is to use addEventListener and postMessage instead, and use the preload script as a bridge between the renderer and the main scripts.

// preload.js
const { ipcRenderer } = require('electron');

process.once('loaded', () => {
  window.addEventListener('message', event => {
    // do something with custom event
    const message = event.data;

    if (message.myTypeField === 'my-custom-message') {
      ipcRenderer.send('custom-message', message);
    }
  });
});


// main.js
const {app, ipcMain, BrowserWindow} = require('electron');

app.on('ready', () => {
  ipcMain.on('custom-message', (event, message) => {
    console.log('got an IPC message', e, message);
  });

  // Create the browser window.
  win = new BrowserWindow({
      backgroundColor: '#fff', // always set a bg color to enable font antialiasing!
      webPreferences: {
        preload: path.join(__dirname, './preload.js'),
        nodeIntegration: false,
        enableRemoteModule: false,
        contextIsolation: true,
        sandbox: true,
        // nativeWindowOpen: true,
      }
  });
  win.loadURL(`file://${path.join(__dirname, 'index.html')}`);


// renderer.js
window.postMessage({
  myTypeField: 'my-custom-message',
  someData: 123,
});

这篇关于电子IPC和节点集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆