电子“要求没有定义”
我在做我需要给访问文件系统(FS)模块的应用程序,但即使nodeIntegration
启用渲染器给了我这个错误:
Uncaught ReferenceError: require is not defined
所有类似的问题,我能找到了一个解决方案,说他们需要把nodeIntegration
上,但是我已经启用它。
这是我main.js:
const electron = require('electron');
const {app, BrowserWindow} = electron;
let win;
app.on('ready', () => {
var { width, height } = electron.screen.getPrimaryDisplay().workAreaSize;
width = 1600;
height = 900;
win = new BrowserWindow({'minHeight': 850, 'minWidth': 1600, width, height, webPreferences: {
contextIsolation: true,
webSecurity: true,
nodeIntegration: true
}});
win.setMenu(null);
win.loadFile('index.html');
win.webContents.openDevTools()
});
我index.js,在index.html的链接为<script src="index.js"></script>
目前只有require("fs");
在里面,我注释掉了所有其他的东西。
我不知道为什么需要仍然即使nodeIntegration
启用不起作用。
当你有nodeIntegration
停用,但没有使用contextIsolation
,你可以使用一个预载脚本揭露它的安全版本全局对象上。 (注:你不应该在整个fs
模块暴露在远程页面!)
下面是这种方式使用预加载脚本的例子:
// main process script
const mainWindow = new BrowserWindow({
webPreferences: {
contextIsolation: false,
nodeIntegration: false,
preload: './preload.js'
}
})
mainWindow.loadURL('my-safe-file.html')
// preload.js
const { readFileSync } = require('fs')
// the host page will have access to `window.readConfig`,
// but not direct access to `readFileSync`
window.readConfig = function () {
const data = readFileSync('./config.json')
return data
}
// renderer.js
const config = window.readConfig()
如果你只加载本地网页,而这些网页不加载或执行不安全的动态内容,那么你可能会重新考虑这一策略的使用contextIsolation
的。如果你想然而保持contextIsolation
上,(你绝对应该,如果你有一个显示不安全内容的机会),你只能用message passing via postMessage
预加载脚本通信。
以下是相同的场景的一个例子的上方,但与contextIsolation
上,并使用消息传递。
// main process script
const mainWindow = new BrowserWindow({
webPreferences: {
contextIsolation: true,
nodeIntegration: false,
preload: './preload.js'
}
})
mainWindow.loadURL('my-unsafe-file.html')
// preload.js
const { readFileSync } = require('fs')
const readConfig = function () {
const data = readFileSync('./config.json')
return data
}
window.addEventListener('message', (event) => {
if (event.source !== window) return
if (event.data.type === 'request') {
window.postMessage({ type: 'response', content: readConfig() })
}
})
// renderer.js
window.addEventListener('message', (event) => {
if (event.source !== window) return
if (event.data.type === 'response') {
const config = event.data.content
}
})
window.postMessage('request')
虽然这肯定是更冗长和难以处理(和力量的东西是异步的,因为消息传递是异步),它也更安全。一对周围的postMessage
API小JS包装可以使这更容易(通过RPC状机构如)一起工作,但要记住,使用contextIsolation
整点是因为你不能信任的渲染,让你的预紧脚本不应该相信它只是通过postMessage
API获取任何消息 - 你应该始终确保您收到以确保您信任的事件。
This slide deck描述者详细为什么关闭节点的整合,而不使用上下文孤立并不总是一个好主意。