sandbox属性加了即“全锁死”:js不执行、表单不提交、弹窗失效、localstorage不可读写,仅postmessage可用;须显式添加allow-scripts等白名单token才能放行对应能力。

sandbox 属性不是“加了就安全”,而是“不加默认全开、加了默认全锁”——只要出现该属性(哪怕值为空),iframe 内所有主动行为立刻被禁用,必须显式放行才能恢复对应能力。
为什么加了 sandbox 就白屏或脚本不执行?
因为 sandbox=""(或仅写 sandbox)等价于启用全部限制:JS 不解析、onclick 失效、fetch() 报错、localStorage 访问被拒、表单点击无反应、window.open() 静默拦截。浏览器不会报错,而是直接静默丢弃这些行为。
常见误判是以为“JS 写错了”或“路径不对”,其实只需在控制台执行:document.querySelector('iframe').sandbox,返回空 DOMTokenList [] 就说明权限没开。
- 只写
<iframe sandbox></iframe>→ 全禁,连alert(1)都不会弹 - 写了
sandbox="allow-scripts"→ JS 可运行,但内联事件(如onclick)仍被屏蔽 - 写了
sandbox="allow-scripts allow-same-origin"→ 仅当src确实与父页同源(协议+域名+端口全一致)时才生效;否则allow-same-origin被浏览器忽略,localStorage依然不可读写
allow-scripts 单独启用时的硬限制
allow-scripts 是最常加的权限,但它只解禁“脚本加载与执行”,并不恢复其他配套能力:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 内联事件处理器(
onclick、onload、javascript:void(0))仍被屏蔽,必须改用addEventListener - 无法调用
document.write()或同步XMLHttpRequest,即使加了该权限 - iframe 的 origin 强制变为
"null",所以仍不能访问window.parent或读取父页面 DOM -
postMessage可用,但接收方必须校验event.origin,不能依赖allow-same-origin绕过验证
哪些组合实际可用,哪些绝对要避开?
按最小权限原则配,拒绝堆砌。生产环境嵌第三方内容时,allow-same-origin 和 allow-top-navigation 基本等于关掉沙箱。
- 只展示带 JS 的广告/图表:
sandbox="allow-scripts allow-popups"(禁表单、禁存储、禁跳转) - 嵌入用户填写的问卷:
sandbox="allow-scripts allow-forms allow-popups"(表单提交走 CORS,不碰同源) - 加载同源可信子系统(如
https://yourapp.com/admin.html):sandbox="allow-scripts allow-same-origin allow-forms"(确认 URL 真同源) - 绝对不要写:
sandbox="allow-scripts allow-same-origin allow-popups allow-forms allow-top-navigation"—— 这和没加sandbox几乎一样危险
localStorage 和 fetch 在沙箱里为什么还是失败?
它们不是靠 allow-scripts 就能用的。存储类 API(localStorage、sessionStorage、indexedDB)默认被禁,且没有通用白名单。Chrome 95+ 支持 allow-storage-access-by-user-activation,但需用户点击触发、且 Firefox/Safari 不支持。
fetch() 是否成功,取决于两个条件:是否开了 allow-scripts(决定能否调用函数),以及目标地址是否满足 CORS(决定请求能否发出)。沙箱不绕过 CORS,只管“能不能发起请求”,不管“请求发到哪去”。
真正可靠的做法是:别让沙箱 iframe 自己存数据;把需要持久化的数据通过 postMessage 传回主页面,由主页面处理存储逻辑——这才是沙箱设计的本意:隔离风险,不隔离通信。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










