一、问题背景:我到底想解决什么?
在复杂前端系统中,我们经常会遇到这样的需求:
-
页面需要嵌入第三方内容 / 子系统
-
希望 样式、脚本互不影响
-
同时又要保证:
- 正常渲染
- 合理交互
- 可控的安全边界
常见方案是 iframe,但一旦深入使用,就会立刻遇到一系列问题:
- Cookie 是否会被注入?
- JS 能否互相访问?
- 样式是否会污染?
- sandbox 一加,页面怎么直接不显示了?
- 不加
allow-same-origin又为什么什么都"坏了"?
这篇文章,就是围绕这些真实问题展开。
二、iframe 的本质:浏览器级别的"硬隔离"
1️⃣ iframe 是什么?
从浏览器角度看,iframe 并不是一个普通 DOM,而是:
一个完整的、独立的浏览上下文(Browsing Context)
它拥有自己的:
- DOM 树
- JS 执行环境
- CSS 作用域
- Cookie / Storage(是否共享取决于策略)
这也是它"隔离性强"的根本原因。
2️⃣ iframe 天生适合做什么?
- 微前端子应用
- 第三方内容嵌入
- 不可信页面展示
- 强安全边界场景
它解决的是"不信任"的问题,而不是"优雅"的问题。
三、sandbox:安全从这里开始,也从这里失控
1️⃣ sandbox 到底干了什么?
当你给 iframe 加上:
css
<iframe sandbox></iframe>
你相当于对它说:
"你什么都不能干。"
包括但不限于:
- ❌ JS 不执行
- ❌ 表单提交被禁
- ❌ 同源身份被剥夺
- ❌ Cookie / localStorage 全部隔离
2️⃣ 为什么加了 sandbox,页面直接空白?
因为很多页面:
- 依赖 JS 渲染
- 依赖同源读取资源
- 依赖 Cookie 维持状态
一旦 sandbox 默认限制生效,页面逻辑上还能加载,但功能全废。
3️⃣ allow-scripts + allow-same-origin 为什么危险?
ini
sandbox="allow-scripts allow-same-origin"
这是一个经典陷阱组合。
原因是:
allow-scripts:允许 JS 执行allow-same-origin:恢复同源身份
⚠️ 一旦两者同时存在:
iframe 内的 JS 可以认为自己是"正常页面"
从规范角度,它已经具备了逃逸 sandbox 的能力。
这也是 MDN 明确标注的安全风险。
四、那我只是不想 Cookie 被注入,怎么办?
❌ 错误直觉
"去掉 allow-same-origin 就好了"
结果是:
- JS 取不到任何资源
- 页面渲染失败
- iframe 内容直接消失
✅ 正确理解
Cookie 注入的本质是:
- 同源 + 凭证传递
控制 Cookie 的正确方式是:
SameSiteHttpOnlySecure- 服务端鉴权策略
而不是指望 iframe sandbox 去"顺便解决"。
五、Shadow DOM:另一种完全不同的"隔离"
1️⃣ Shadow DOM 隔离的是什么?
Shadow DOM 隔离的是:
- 样式作用域
- DOM 结构可见性
但它:
- ❌ 不隔离 JS
- ❌ 不隔离 Cookie
- ❌ 不隔离安全上下文
它解决的是:
组件级的可维护性问题
而不是安全问题。
2️⃣ iframe vs Shadow DOM 对比
| 维度 | iframe | Shadow DOM |
|---|---|---|
| 样式隔离 | ✅ 强 | ✅ 中 |
| JS 隔离 | ✅ 强 | ❌ |
| 安全边界 | ✅ | ❌ |
| 通信成本 | 高 | 低 |
| 性能 | 较重 | 轻 |
| 使用复杂度 | 高 | 中 |
一句话总结:
iframe 是安全隔离工具
Shadow DOM 是工程隔离工具