- 是否可以在不启用 nodeIntegration 的情况下使用 ipcRenderer?
这是可能的,但很繁琐。它可以通过使用preload
脚本来完成。
- 如果是,我该怎么做,为什么这么多资源会排除这些信息?
可以使用preload
如下所示的脚本。但是,这不被认为是安全的。大多数现有文档没有显示最佳安全实践。
后面给出了一个更安全的例子。
// 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 时也会变得复杂,因为输出文件可能是不同的路径。
- 如果不是,我用什么?
编辑
正如@Yannic 指出的那样,Electron 现在支持另一个选项,称为contextBridge
. 这个新选项可以更简单地解决问题。有关 的信息contextBridge
,请查看电子文档:https : //www.electronjs.org/docs/tutorial/context-isolation
然而,即使contextBridge
你不应该尝试暴露整个电子 API,只是你为你的应用程序设计的一个有限的 API
如上所述,虽然可以使用如上所示的 ipcRenderer,但当前的电子安全建议也建议启用contextIsolation
. 这将使上述方法无法使用,因为您无法再向全局范围添加数据。
AFAIK 最安全的建议是使用addEventListener
和postMessage
代替,并使用预加载脚本作为渲染器和主脚本之间的桥梁。
// 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,
});