我谈了很多关于Electron安全的问题。但是,前端完全访问你的系统并不是一个好主意。Electron推荐如何处理?
当前的解决方案--是预加载脚本。
我们仍然有前端和后端代码,但我们还有第三种代码------预加载脚本。它在将控制权交给常规代码之前,初始化并执行任何高级权限的操作。
启用预加载脚本
让我们从我们在上一篇文章开始。我们需要去掉nodeIntegration:true和contextIsolation:false。
出于某种原因,Electron真的希望预加载路径是绝对路径,而不是相对路径:
js
let { app, BrowserWindow } = require("electron")
function createWindow() {
let win = new BrowserWindow({
webPreferences: {
preload: `${__dirname}/preload.js`,
},
})
win.maximize()
win.loadFile("index.html")
}
app.on("ready", createWindow)
app.on("window-all-closed", () => {
app.quit()
})
预加载脚本
让我们将runCommand
移动到preload.js
,并使用contextBridge
公开它:
js
let child_process = require("child_process")
let { contextBridge } = require("electron")
let runCommand = (command) => {
return child_process.execSync(command).toString().trim()
}
contextBridge.exposeInMainWorld(
"api", { runCommand }
)
contextBridge.exposeInMainWorld
定义了我们在前端暴露的内容。在本例中,将runCommand 挂载到 window.api。
使用预加载脚本
在前端脚本中,我们只需要更改两行-删除require
。因为,它不再起作用,并调用我们公开的方法window.API.runCommand
而不是child_process.execSync
:
js
form.addEventListener("submit", (e) => {
e.preventDefault()
let command = input.value
let output = window.api.runCommand(command)
createTerminalHistoryEntry(command, output)
input.value = ""
input.scrollIntoView()
})
代码
app.js
js
let form = document.querySelector("form")
let input = document.querySelector("input")
let terminalHistory = document.querySelector("#history")
function createInputLine(command) {
let inputLine = document.createElement("div")
inputLine.className = "input-line"
let promptSpan = document.createElement("span")
promptSpan.className = "prompt"
promptSpan.append("$")
let inputSpan = document.createElement("span")
inputSpan.className = "input"
inputSpan.append(command)
inputLine.append(promptSpan)
inputLine.append(inputSpan)
return inputLine
}
function createTerminalHistoryEntry(command, commandOutput) {
let inputLine = createInputLine(command)
let output = document.createElement("div")
output.className = "output"
output.append(commandOutput)
terminalHistory.append(inputLine)
terminalHistory.append(output)
}
form.addEventListener("submit", (e) => {
e.preventDefault()
let command = input.value
let output = window.api.runCommand(command)
createTerminalHistoryEntry(command, output)
input.value = ""
input.scrollIntoView()
})