上下文隔离
这意味着,实际上,您的预加载脚本访问的 window
对象并不是网站所能访问的对象。 例如,如果您在预加载脚本中设置 window.hello = 'wave'
并且启用了上下文隔离,当网站尝试访问window.hello
对象时将返回 undefined。
自 Electron 12 以来,默认情况下已启用上下文隔离,并且它是 所有应用程序推荐的安全设置。
在渲染进程中,预加载脚本暴露给已加载的页面 API 是一个常见的使用方式。 当上下文隔离时,您的预加载脚本可能会暴露一个常见的全局window
对象给渲染进程。 此后,您可以从中添加任意的属性到预加载在脚本。
preload.js
doAThing()
函数可以在渲染进程中直接使用。
// 在渲染器进程使用导出的 API
window.myAPI.doAThing()
之后:启用上下文隔离
Electron 提供一种专门的模块来无阻地帮助您完成这项工作。 contextBridge 模块可以用来安全地从独立运行、上下文隔离的预加载脚本中暴露 API 给正在运行的渲染进程。 API 还可以像以前一样,从 window.myAPI
网站上访问。
preload.js
// 在上下文隔离启用的情况下使用预加载
const { contextBridge } = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
})
renderer.js
请阅读 contextBridge
的文档,以全面了解其限制。 例如,您不能在 contextBridge 中暴露原型或者 Symbol。
单单开启和使用 contextIsolation
并不直接意味着您所做的一切都是安全的。 例如,此代码是 不安全的。
preload.js
// ❌ 错误使用
contextBridge.exposeInMainWorld('myAPI', {
send: ipcRenderer.send
})
preload.js
// ✅ 正确使用
contextBridge.exposeInMainWorld('myAPI', {
loadPreferences: () => ipcRenderer.invoke('load-prefs')
如果您正在使用 TypeScript 构建 Electron 应用程序,您需要给通过 context bridge 暴露的 API 添加类型。 渲染进程的 window
对象将不会包含正确扩展类型,除非给其添加了 。
例如,在这个 preload.ts
脚本中:
preload.ts
您可以创建一个 类型声明文件,并且全局增强 Window
接口。
renderer.d.ts
export interface IElectronAPI {
loadPreferences: () => Promise<void>,
}
declare global {
interface Window {
electronAPI: IElectronAPI
}
}
renderer.ts
window.electronAPI.loadPreferences()