跳到主要内容

sandbox: true/false 对 preload 可用 API 有什么影响?

考察点​

  • sandbox 模式下 preload 的能力边界
  • "preload 里 require fs 报错"的经典问题

参考答案​

1. 两种模式的能力对比​

sandbox: falsesandbox: true(推荐)
Node 内置模块(fs/path/os)✅ 完整可用❌ 不可用
npm 包 require✅❌
require('electron')✅ 全部⚠️ 仅 ipcRenderer、contextBridge、webFrame 等
其他可用完整 Nodeevents、timers、url 等极少数 polyfill
OS 级沙箱保护无有(Chromium 沙箱限制系统调用)

sandbox 开启时,preload 里的 require 是一个阉割版:

// sandbox: true 的 preload 中
const { ipcRenderer, contextBridge } = require('electron'); // ✅ 可用
const fs = require('fs'); // ❌ 报错:module not found
const _ = require('lodash'); // ❌ 报错

2. 典型踩坑场景​

"我想在 preload 里读个本地配置文件再暴露给页面"

// ❌ sandbox: true 下失败
const fs = require('fs');
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
contextBridge.exposeInMainWorld('config', config);

正确解法:把 Node 能力挪到主进程,preload 只走 IPC

// preload(sandbox 兼容写法)
contextBridge.exposeInMainWorld('api', {
getConfig: () => ipcRenderer.invoke('config:get'), // 主进程读文件
});

// 主进程
ipcMain.handle('config:get', async () => {
return JSON.parse(await fs.readFile(configPath, 'utf-8'));
});

代价是多一次异步 IPC(配置从同步读取变异步获取),换来整个渲染进程被 OS 沙箱保护。

3. 什么时候可以关 sandbox​

只有 preload 必须直接用 Node 能力且无法走 IPC 的场景,例如:

  • preload 需要加载一个大的 npm 工具库做页面注入前的预处理
  • 遗留项目迁移过渡期

关 sandbox 时的补救措施:

  • contextIsolation 必须保持 true
  • 桥接 API 审查标准提高一档(preload 权限大,泄露面更大)
  • 明确记录该窗口为什么需要 sandbox: false,防止蔓延成默认配置

4. 架构原则​

理想分层:
┌──────────────────────────────┐
│ 渲染进程(sandbox) │ 纯 UI,无 Node
│ ↑ 白名单桥 │
│ preload(sandbox) │ 只有 ipcRenderer + contextBridge
│ ↑ IPC │
│ 主进程 │ 所有 Node 能力、文件、系统调用
└──────────────────────────────┘

preload 的宿命是"桥,不是处理器"——它存在的意义是把主进程能力安全地摆渡给页面,而不是自己干活。凡是想在 preload 里干的活,99% 都应该放主进程。

5. 默认值注意​

  • Electron 20+:无 preload 的渲染进程默认 sandbox
  • 有 preload 时默认 sandbox 是 false(历史原因)——所以推荐显式写 sandbox: true,不依赖默认值

面试话术​

sandbox 开启后 preload 的 require 是阉割版:electron 里只有 ipcRenderer/contextBridge/webFrame 可用,fs 和 npm 包全废。这是"preload 读文件报错"的根因。正确架构是把 Node 能力全部沉到主进程,preload 只做 IPC 摆渡;显式写 sandbox: true 不依赖默认值。

常见追问​

  • sandbox 怎么实现限制的? Chromium 沙箱在 OS 层限制进程系统调用(seccomp/Seatbelt),渲染进程内 V8 暴露的 Node API 被裁剪。
  • sandbox 与 contextIsolation 的关系? 正交:sandbox 管进程与 OS 的边界,contextIsolation 管 preload 与页面的 JS 边界,两个都开才是完整防线。