Electron 页面加载方式有两种:
- 加载本地文件
- 通过 http 网络请求页面
加载本地资源的文件可以很方便的使用本地环境。此处不再赘述。但是在 http 请求的资源中,我们如何调用到 electron/NodeJS 的 API 呢?答案是使用 electron 提供的 preload 方法来给页面附加 nodejs/electron 运行环境。
关于 preload
preload
是 electron 的 BrowserWindow
提供的一种预加载的脚本。该脚本在页面运行其他脚本之前运行。在该脚本中,无论页面是否集成了 Nodejs,此脚本中的内容都可以访问所有的 NodeJS API。
preload
的详细信息参考BrowserWindow
代码参考
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
console.log("111111")
window.fromWebToElectron('test 11111', function(a){
console.log("get data from aaaaa ", a)
})
window.ifElectronWantClose = function(a){
console.log("electron told window need to close, ", a)
}
window.saveDataToFile('aaa', 'aaaa1', function(a){
console.log('electron write data aaaa1 to file aaa');
})
window.saveDataToFileSuccessListener = function(a){
console.log("electron write data aaaa1 to file, ", a)
}
</script>
</head>
<body>
First Pages
</body>
</html>
main.js
const {app, BrowserWindow, ipcMain} = require('electron')
const path = require('path')
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
//支持nodejs
nodeIntegration: true,
contextIsolation: false,
preload: path.join(__dirname, 'preload.js')
}
})
// and load the index.html of the app.
mainWindow.loadURL(html 地址)
mainWindow.on('closed', function () {
mainWindow = null
})
}
ipcMain.on('close', (e, a) => {
mainWindow.webContents.send('ifElectronWantClose', [a]);
});
ipcMain.on('write_file_success', (e, a) => {
mainWindow.webContents.send('saveDataToFileSuccessListener', [a]);
});
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', function () {
if (mainWindow === null) createWindow()
})
preload.js
// electron接收传参或主动talk
// preload.js
let {ipcRenderer} = require('electron');
let fs = require('fs');
let path = require('path');
window.saveDataToFile = function (name, fileString, callback) {
let fPath = path.join('C:\\Users\\melon\\Desktop\\新建文件夹', name);
fs.writeFileSync(fPath, fileString);
callback(`write file to ${'fPath'} success`);
ipcRenderer.send('write_file_success', 'args aaa'); // 比如收到请求关闭窗口
};
ipcRenderer.on('saveDataToFileSuccessListener', (e, args) => {
window.saveDataToFileSuccessListener(args[0]);
});
window.fromWebToElectron = function (a, callback) {
console.log('electron收到远端的传参', a);
callback('config result'); // 回调给远端的请求数据,如 config
ipcRenderer.send('close', 'args bbb'); // 比如收到请求关闭窗口
};
ipcRenderer.on('ifElectronWantClose', (e, args) => {
window.ifElectronWantClose(args[0]);
});
至此,我们只要在 preload 中提供了适当的方法,就可以通过 https 加载远端的网页操作本地资源了。
运行效果如图:
关于 sandbox
当 webPreferences
中 sandbox
设置为 true 的时候,preload 中的脚本能够调用的 API 被限制了。仅能够访问到 electron 的一部分 API。但是这时候可以通过 IPC 通信的机制,使用主进程来访问被限制的 API。对安全考虑较多的,可以考虑使用这个。
注意:如果报错Uncaught TypeError: window.fromWebToElectron is not a function
at index.html:26,请在主进程中加上下面两句
nodeIntegration: true,
contextIsolation: false,