- 是否可以在不启用nodeIntegration的情况下使用ipcRenderer?
可以,但比较麻烦。可以通过使用preload
脚本来实现。
- 如果可以,如何做到这一点,为什么会有这么多资源排除这些信息?
可以通过使用下面指示的preload
脚本来实现。然而,这不被视为安全的做法。大部分现有的文档并没有展示最佳的安全实践。
下面给出一个更加安全的例子。
const electron = require('electron');
process.once('loaded', () => {
global.ipcRenderer = electron.ipcRenderer;
});
const {app, BrowserWindow} = require('electron');
app.on('ready', () => {
win = new BrowserWindow({
backgroundColor: '#fff',
webPreferences: {
preload: path.join(__dirname, './preload.js'),
nodeIntegration: false,
enableRemoteModule: false,
}
});
win.loadURL(`file://${path.join(__dirname, 'index.html')}`);
注意:预加载脚本的路径必须是绝对路径,如果使用webpack/babel可能会变得复杂,因为输出文件可能在不同的路径下。
- 如果不是绝对路径,我该用什么?
编辑:如@Yannic所指出的那样,Electron现在支持另一种选项,称为contextBridge
。这个新选项可能更简单地解决了问题。有关contextBridge
的信息,请查看Electron文档:https://www.electronjs.org/docs/tutorial/context-isolation
但即使使用 contextBridge
,您也不应该尝试公开整个Electron API,而只能公开您为您的应用程序设计的受限API
如上所述,虽然可以像上面展示的那样使用ipcRenderer,但当前的Electron安全建议也建议启用contextIsolation
。这将使上述方法无法使用,因为您将不能再向全局范围添加数据。
据我所知,最安全的建议是使用addEventListener
和postMessage
,并将预加载脚本用作渲染器和主脚本之间的桥梁。
const { ipcRenderer } = require('electron');
process.once('loaded', () => {
window.addEventListener('message', event => {
const message = event.data;
if (message.myTypeField === 'my-custom-message') {
ipcRenderer.send('custom-message', message);
}
});
});
const {app, ipcMain, BrowserWindow} = require('electron');
app.on('ready', () => {
ipcMain.on('custom-message', (event, message) => {
console.log('got an IPC message', e, message);
});
win = new BrowserWindow({
backgroundColor: '#fff',
webPreferences: {
preload: path.join(__dirname, './preload.js'),
nodeIntegration: false,
enableRemoteModule: false,
contextIsolation: true,
sandbox: true,
}
});
win.loadURL(`file://${path.join(__dirname, 'index.html')}`);
window.postMessage({
myTypeField: 'my-custom-message',
someData: 123,
});
nodeIntegration
可以启用/禁用 NodeJS 的使用,由于 Electron 是一个 NodeJS 模块,因此您无法在没有 NodeJS 的情况下使用它。因此,如果您想要使用 Electron 的ipcRenderer
,则必须启用 NodeJS。 - Alexander LeithnernodeIntegration
设置为false
,则无法在main
和renderer
进程之间进行通信。我实际上很好奇当它被设置为false
时,Electron 的实际用途是什么,现在他们已经将其设置为默认值。 - jayarjonodeIntegration
默认值是false
,所以不需要它吗? - oldboynodeIntegration
被禁用时,您仍然可以通过其他方式与主线程通信。例如,您可以建立一个 WebSocket 连接或使用标准的 HTTP 方法(如在后台发送GET
/POST
JSON 数据)。Luke H 的下面回答提供了对您三个问题的详细解释和解决方案,我建议将其标记为被接受的答案。 - jacobq