[英]Electron “require is not defined”
我正在创建一个应用程序,我需要访问文件系统(fs)模块,但是即使启用了nodeIntegration
,渲染器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
,(如果您有可能显示不安全的内容,则肯定应该这样做),您只能通过postMessage
传递消息与preload脚本进行通信。
以上是上述相同场景的示例,但使用了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获得的任何消息 - 您应该始终验证您收到的事件以确保您信任它。
这个幻灯片详细描述了为什么在不使用上下文隔离的情况下关闭节点集成并不总是一个好主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.