generator不能实现微沙箱底座,因其仅提供协程式控制流,缺乏执行隔离能力;真正的沙箱必须依赖iframe或web worker等原生隔离机制,generator仅可作为任务编排的语法糖提升可维护性。

直接用 Generator 实现“微沙箱底座”并不现实——Generator 本身不提供执行隔离、作用域控制或代码沙箱能力,它只是函数执行流程的暂停/恢复机制。真正安全的微沙箱必须依赖浏览器原生隔离能力(如 iframe、Web Worker、Realm(尚未广泛支持)),而 Generator 可作为其内部任务编排或副作用调度的语法糖,用于提升可读性与可控性。
明确 Generator 的定位:协程式控制流,不是沙箱
Generator(function* + yield)本质是可中断的函数,适合封装异步逻辑、迭代器或状态机。它运行在当前 JS 执行上下文中,共享全局作用域、原型链和所有可访问对象——无法阻止恶意代码访问 window、修改 Array.prototype 或触发 XSS。因此,它不能替代沙箱,但可以配合沙箱使用:
- 在 iframe 沙箱中,用 Generator 编排模块加载、资源请求、生命周期钩子等串行逻辑
- 在 Web Worker 中,用 Generator 将长耗时计算拆分为可中断的 yield 步骤,避免阻塞主线程
- 作为沙箱通信协议的“指令生成器”,将用户脚本解析为受控的
yield { type: 'eval', code: '...' }操作序列,由沙箱宿主统一校验并执行
构建真实隔离底座:必须依赖 iframe 或 Worker
纯原生 JS 中唯一可靠、零依赖的强隔离方案是 iframe(启用 sandbox 属性):
- 创建无源、无脚本、无插件的空 iframe:
const iframe = document.createElement('iframe'); iframe.sandbox = 'allow-scripts'; iframe.src = 'data:text/html,'; - 通过
iframe.contentWindow获取独立全局环境,再注入白名单 API(如仅暴露fetch封装、JSON、Date等安全子集) - 禁止直接
eval或Function构造器;所有代码执行需经 AST 分析或正则白名单过滤(如只允许字面量、函数声明、安全调用)
Worker 方案适合 CPU 密集型任务,但无法操作 DOM;若需 DOM 操作,iframe 是不可绕过的基石。
用 Generator 增强沙箱可维护性(示例)
假设你已建立 iframe 沙箱环境,可用 Generator 封装一次安全执行流程:
function* sandboxedTask(sandboxWin, code) {
yield { type: 'log', msg: '开始校验' };
if (!isValidCode(code)) yield { type: 'error', reason: '含非法语法' };
<p>yield { type: 'log', msg: '注入白名单 API' };
injectSafeAPIs(sandboxWin);</p><p>yield { type: 'log', msg: '执行代码' };
const result = sandboxWin.eval(code); // 实际应走更安全的封装</p><p>yield { type: 'success', data: result };
}</p><p>// 调用时可逐帧控制、记录、中断
for (const step of sandboxedTask(iframe.contentWindow, '1+1')) {
console.log(step);
if (step.type === 'error') break;
}</p>
这不增加安全性,但让沙箱行为变得可追踪、可调试、可组合。
关键安全细节不能省略
即使用了 Generator 编排,以下隔离措施仍必须硬编码实现:
- 作用域隔离:iframe 内不继承父页面 cookie、localStorage、document;Worker 完全无 DOM 访问权
-
API 白名单:手动挂载而非继承
iframe.contentWindow原生对象(如重写fetch以限制域名、禁用 credentials) -
动态代码拦截:禁止
eval、new Function、setTimeout("...")字符串形式;所有执行入口必须经过静态分析或 AST 遍历校验 -
内存与事件隔离:监听
message时严格校验消息结构与来源(event.source === iframe.contentWindow),避免原型污染或循环引用泄漏
Generator 只是让这些步骤写起来更清晰,而不是让它们自动生效。











