这是我的设置:
步骤1。使用以下代码创建preload.js文件:
window.ipcRenderer = require('electron').ipcRenderer;
第2步。通过webPreferences将文件预加载到main.js中:
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
preload: __dirname + '/preload.js'
}
});
第3步。在渲染器中:
console.log(window.ipcRenderer); // Works!
现在,按照Electron的安全性指南,我希望转向contextIsolation=true
:https://electronjs.org/docs/tutorial/security#3-enable-context-isolation-for-remote-content
步骤2之二。
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
contextIsolation: true,
nodeIntegration: false,
preload: __dirname + '/preload.js'
}
});
步骤3之二。在渲染器中:
console.log(window.ipcRenderer); // undefined
问题:contextIsolation=true
时可以使用ipcRenderer吗?
答案 0 :(得分:4)
您可以遵循设置outlined here。 secure-electron-template
中正在使用此设置,基本上,您可以执行以下操作:
main.js
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
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
<!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>
您还可以在contextIsolation设置为true的渲染器进程中使用ipcRenderer。 contextBridge是您要使用的,尽管有一个current bug阻止了您在渲染器过程中调用ipcRenderer.on。您所能做的就是从渲染器进程发送到主进程。
此代码摘自secure-electron-template电子安全模板,该模板是为安全性而构建的。 (我是作者)
preload.js
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld(
"electron",
{
ipcRenderer: ipcRenderer
}
);
main.js
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
答案 1 :(得分:0)
答案 2 :(得分:0)
请检查this。这个对我有用。我正在使用CRA和Electron。
preload.js
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
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
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
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 (渲染器)
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
{
"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"
}
}