返回博客列表

Electron的webPreferences常用配置详解

详解webPreferences的contextIsolation和nodeIntegration配置

preload配置项

ebPreferences有个preload配置项:preload: path.join(__dirname, 'preload.js') 用来配置预加载脚本,用于向渲染进程暴露有限 API

示例代码:

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  getAppInfo: () => ipcRenderer.invoke('get-app-info'),
});

contextIsolation和nodeIntegration

这两个配置如果完全不设置时等价于:

webPreferences: {
  contextIsolation: true,
  nodeIntegration: false,
}

关于contextIsolation

控制 Electron 内部是否把页面 JS 世界和 preload 脚本世界隔离开。 true(推荐默认值):两个世界分开,页面不能直接碰到 preload 里注入的东西,必须通过 contextBridge 暴露 false:不隔离,页面和 preload 共享同一个 JS 环境

两个“世界”

开启 contextIsolation: true 后,渲染进程里会有两个独立的 JavaScript 上下文:

┌─────────────────────────────────────────┐
│           渲染进程 (Renderer)            │
│                                         │
│  ┌─────────────────┐  ┌──────────────┐  │
│  │  Isolated World │  │  Main World  │  │
│  │  (隔离世界)      │  │  (主世界)     │  │
│  │                 │  │              │  │
│  │  preload.js     │  │  renderer.js │  │
│  │  ✅ require()   │  │ ❌require() │  │
│  │  ✅ Node API    │  │  像普通网页   │  │
│  └─────────────────┘  └──────────────┘  │
└─────────────────────────────────────────┘
  • Isolated World:preload.js 在这里跑,可以用 require、Node API
  • Main World:index.html 里 <script src=“renderer.js”> 在这里跑,行为和 Chrome 网页里的 JS 一样

两者互不可见:renderer.js 拿不到 preload 里的变量,preload 也碰不到页面里的 window 对象(除非用 contextBridge 主动暴露)。

如果关掉隔离:contextIsolation: false 这时只有一个世界,页面和 preload 共享环境,如果此时又把nodeIntegration: true开启了,那么页面的 renderer.js 就能直接使用NODE APi,IPC 在 renderer.js 里直接写就行,此时preload.js就没有什么必要了。

但是,如果关掉隔离,那么页面一旦被注入恶意 JS,就能直接 require(‘child_process’) 执行系统命令,就不安全了。故官方推荐推荐默认应开启。

关于nodeIntegration配置

允许渲染进程里的页面脚本使用 Node.js API,例如:const { ipcRenderer } = require(‘electron’) true:页面里可以用 require、process、Buffer 等 false:页面像普通浏览器网页,不能直接用 Node

总结:

  1. 必须nodeIntegration: true+contextIsolation: false 页面才可以使用node api
  2. preload.js文件始终能使用node api,不受到nodeIntegration影响
  3. 满足nodeIntegration: flasecontextIsolation: true 任意一个,页面都不能直接使用node api

在现代 Electron 项目里,preload.js 几乎是标准做法,尤其是页面要和主进程通信时。reload.js 是页面和主进程之间的安全桥梁,只暴露必要 API,而不是把整个 Node/Electron 权限交给页面。