eval,不允许 new Function,也不允许动态编译的代码。当某个功能确实需要这些能力时(模板引擎、代码 playground、运行 AI 生成的片段),Manifest V3 提供了 sandbox 页面:用放弃 chrome.* API 访问权限换取一份更宽松 CSP 的扩展页面。
声明页面
manifest.json
sandbox.html:直接引用你的 .ts/.tsx 即可构建。入口写法参见 HTML 指南。
sandbox 页面能做什么、不能做什么
| 能力 | Sandbox 页面 |
|---|---|
eval、new Function | 是 |
| 独立 origin(与其他页面隔离) | 是 |
chrome.* 扩展 API | 否 |
直接访问 chrome.storage | 否 |
与宿主页面进行 postMessage 通信 | 是 |
嵌入与通信
在一个普通扩展页面中用 iframe 加载 sandbox,然后通过postMessage 通信:
newtab.html
newtab.ts
sandbox.ts
chrome.* 访问权限,并扮演中间人的角色:它读取 storage、调用 API,并把纯数据传入和传出 sandbox。
别搞混了:background.type
一个常见的混淆:"background": {"type": "module"} 和 sandbox 化毫无关系。它声明 background service worker 是一个 ES 模块,这样 import 语句在注册时就能正常工作。当你的 background 入口使用 ESM 语法时,Extension.js 会自动设置它,因此你几乎不需要手写。如果你的疑惑是 service worker 里的 import 失败,请看 Background 脚本;如果是关于运行动态代码,那你就来对地方了。
自定义 sandbox CSP
你可以通过 manifest 中的content_security_policy.sandbox 进一步放宽或收紧 sandbox 的 CSP。请把 script-src 收得尽可能窄——只满足该功能所需即可;sandbox 的目的是把动态代码关起来,而不是为了绕过安全审查。安全清单 列出了审核者会关注的点。

