我正在为自己的目的创建一个电子应用程序。我的问题是,当我在我的HTML页面内使用节点函数时,它抛出了一个错误:
'require()'没有定义。
是否有办法在所有HTML页面中使用Node功能?如果有可能,请给我一个如何做到这一点的例子或提供一个链接。下面是我试图在我的HTML页面中使用的变量:
var app = require('electron').remote;
var dialog = app.dialog;
var fs = require('fs');
这些是我在电子中所有HTML窗口中使用的值。
首先,@Sathiraumesh解决方案给电子应用程序留下了巨大的安全问题。想象一下,你的应用程序正在为messenger.com添加一些额外的功能,例如,当你有未读消息时,工具栏的图标会改变或闪烁。所以在你的main.js文件中,你像这样创建新的BrowserWindow(注意我故意拼错了messenger.com):
app.on('ready', () => {
const mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
});
mainWindow.loadURL(`https://messengre.com`);
});
如果messengre.com是一个恶意网站,想要伤害你的电脑怎么办?如果你设置了nodeIntegration: true,这个站点可以访问你的本地文件系统,并且可以执行以下命令:
require('child_process').exec('rm -r ~/');
您的主目录消失了。
解决方案
只暴露你需要的,而不是一切。这是通过使用require语句预加载javascript代码来实现的。
// main.js
app.on('ready', () => {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: `${__dirname}/preload.js`
}
});
mainWindow.loadURL(`https://messengre.com`);
});
// preload.js
window.ipcRenderer = require('electron').ipcRenderer;
// index.html
<script>
window.ipcRenderer.send('channel', data);
</script>
现在糟糕的messengre.com不能删除你的整个文件系统。
我所要做的只是在我的html页面中要求一个js文件,因为我正在遵循的教程。但是,我打算使用远程模块,所以安全性是最重要的。我在上面修改了迈克尔的答案,所以我发布了出来,纯粹是为了那些像我一样花了几个小时寻找安全替代“要求”的人。如果代码不正确,请随时指出来。
main.js
const electron = require('electron');
const app=electron.app;
const BrowserWindow=electron.BrowserWindow;
const ipcMain=electron.ipcMain;
const path=require('path');
const url=require('url');
let win;
function createWindow(){
win=new BrowserWindow({
webPreferences:{
contextIsolation: true,
preload: path.join(__dirname, "preload.js")
}
});
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file',
slashes: true
}));
win.on('close', function(){
win=null
});
}
app.on('ready', createWindow);
preload.js
const electron=require('electron');
const contextBridge=electron.contextBridge;
contextBridge.exposeInMainWorld(
"api", {
loadscript(filename){
require(filename);
}
}
);
index . html
<!DOCTYPE html>
<html>
<head>
<title>Hello World App</title>
</head>
<body>
<h1>Hello World</h1>
<button id="btn">Click</button>
</body>
<script>
window.api.loadscript('./index.js');
</script>
</html>
index.js
const btn = document.getElementById('btn');
btn.addEventListener('click', function(){
console.log('button clicked');
});
我特别想知道这是否仍然存在安全风险。谢谢。
你必须在webPreferences中启用nodeIntegration才能使用它。见下文,
const { BrowserWindow } = require('electron')
let win = new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
})
win.show()
在电子5.0中有一个突破性的api变化(关于存储库的公告)。在最近的版本中,nodeIntegration默认设置为false。
由于Node.js集成了Electron, DOM中插入了一些额外的符号,如module, exports, require。这给一些库带来了问题,因为它们想要插入具有相同名称的符号。要解决这个问题,你可以在Electron中关闭节点集成:
但是如果你想保留使用Node.js和Electron api的能力,你必须在包含其他库之前重命名页面中的符号:
<head>
<script>
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
<script type="text/javascript" src="jquery.js"></script>
</head>