sandbox是限制外部脚本的第一道硬闸:不加则全放行,加了(含空值)即全锁死,仅sandbox="allow-scripts"可启用外链脚本加载,但禁内联事件、eval及动态注入,且必须静态声明、配合csp与origin校验才安全。

直接禁用外部脚本执行,靠 sandbox 属性最有效——但必须写对值,否则要么全放行(不加属性),要么全锁死(sandbox="")。
为什么 sandbox 是限制外部脚本的第一道硬闸
不加 sandbox 的 <iframe></iframe> 会无条件执行 src 指向的任何 JS,包括第三方 CDN 脚本;而只要写了 sandbox(哪怕空值),浏览器立刻拒绝所有脚本执行,连 <script src="https://cdn.com/evil.js"></script> 都不会加载。这不是“拦截”,是“不解析”。
-
sandbox=""或sandbox(无值)→ 所有脚本、表单、弹窗、localStorage全禁,控制台静默,Network 显示net::ERR_BLOCKED_BY_RESPONSE - 想让外部脚本运行,必须显式写
sandbox="allow-scripts",且仅此一项就足够启动外链脚本加载 -
allow-scripts不恢复内联事件(如onclick)、eval()、javascript:void(0),这些仍被屏蔽 - 动态设置
iframe.sandbox = "allow-scripts"无效,属性必须在 DOM 插入前就存在
sandbox="allow-scripts" 能跑哪些外部脚本,不能跑哪些
开了 allow-scripts 后,只有满足特定加载方式和来源策略的外部脚本才能执行:
- ✅ 可执行:
<script src="https://trusted.example/script.js"></script>(需服务端返回Access-Control-Allow-Origin头,或同源) - ❌ 不可执行:
<script src="http://insecure.net/bad.js"></script>(协议不匹配,HTTPS 页面拒载 HTTP 资源) - ❌ 不可执行:
<script src="data:text/javascript,alert(1)"></script>(data:协议默认被 sandbox 拦截,除非显式加allow-scripts+allow-same-origin,但后者极危险) - ⚠️ 风险点:若外链脚本本身又动态
document.write()或创建新<script></script>标签,这些行为仍被禁止——allow-scripts只放行初始外链加载,不递归授权
如何防止外部脚本绕过 sandbox 加载恶意资源
仅靠 sandbox="allow-scripts" 不够,攻击者可能让外链脚本再拉取未受控代码。需叠加防御:
- 配合 CSP 的
script-src:在父页面设Content-Security-Policy: script-src 'self' https://trusted.example',它会约束 iframe 内脚本的后续 fetch/import 行为(注意:CSP 对 iframe 内容本身不生效,但对其发起的子资源请求有效) - 禁用
allow-same-origin:一旦加上,外部脚本就能读取自身 localStorage、发起同源 fetch,甚至通过document.write()注入新脚本——这等于把沙箱钥匙交出去 - 避免使用
srcdoc+ 外部脚本混合:例如<iframe sandbox="allow-scripts" srcdoc="<script src='https://evil.com/xss.js'></script>"></iframe>,srcdoc内容被视为同源,但外链脚本仍受 sandbox 约束;不过这种写法易混淆权限边界,不推荐 - 校验
postMessage来源:若外部脚本需与父页通信,父页监听时必须检查event.origin,不能只依赖sandbox放行
生产环境嵌第三方脚本时最简安全组合
广告、分析、用户上传 HTML 预览等场景,目标不是“让它全跑”,而是“让它只做指定事”:
- 仅执行 JS + 弹窗(如分享按钮):
sandbox="allow-scripts allow-popups" - JS + 表单提交(如嵌入反馈):
sandbox="allow-scripts allow-forms",后端必须支持 CORS,否则提交 403 - 绝对禁止:
allow-same-origin、allow-top-navigation、allow-downloads(旧浏览器忽略,新版 Chrome 89+ 才支持,但风险高) - 验证是否生效:控制台执行
document.querySelector('iframe').sandbox,返回的是真实生效的DOMTokenList,不是 HTML 字符串——这是唯一可信的调试依据
真正容易被忽略的是:sandbox 不是“开关”,是白名单;它不管脚本来自哪,只管“允许做什么”。哪怕你信任某个 CDN,只要没显式授权,它的脚本照样进不来;而一旦授权,它就拥有了对应能力,没有二次过滤机制。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











