sandbox="allow-scripts"仅允许外链脚本执行,禁用内联脚本、事件处理器、eval等所有内联执行能力,且不恢复DOM访问、存储或跨上下文通信权限。

为什么写了 sandbox="allow-scripts" 还是 alert 不出来
因为 allow-scripts 只解禁外链脚本(<script src="..."></script>),不恢复任何内联执行能力。浏览器会静默忽略:<script>alert(1)</script>、onclick="alert(1)"、javascript:void(0)、eval()、document.write()——连控制台都不会报错,更不会弹窗。
验证方式:打开控制台执行 document.querySelector('iframe').sandbox,返回的 DOMTokenList 里必须包含 "allow-scripts" 才算生效;若为空数组 [],说明实际没加或被覆盖了。
- 必须在 iframe 插入 DOM 前就写死属性值,
iframe.sandbox = "allow-scripts"动态设置无效 -
sandbox="allow-scripts "(末尾带空格)会被当成空值,等同于全锁死 - 外链脚本要能执行,服务端还得返回合法的
Access-Control-Allow-Origin头
allow-scripts 能跑什么、不能碰什么
allow-scripts 是多数第三方组件(广告、图表、支付 SDK)的最低可行权限,但它有明确边界:
- ✅ 可运行:
<script src="https://cdn.example.com/widget.js"></script>(CORS 允许时) - ✅ 可运行:该脚本内部调用
fetch()、addEventListener()、setTimeout() - ❌ 不可运行:
<button onclick="fetch('/api')">Submit</button>→ 必须改用 JS 绑定事件 - ❌ 不可访问:
window.parent、document.cookie、localStorage—— origin 强制为"null" - ⚠️ 注意:脚本里再
document.write("<script>...</script>")仍被拦截,不递归授权
常见错误写法与真实后果
很多看似“差不多”的写法,实际效果天差地别:
立即学习“前端免费学习笔记(深入)”;
-
sandbox=""或sandbox(无值)→ 全锁死,白屏 +net::ERR_BLOCKED_BY_RESPONSE -
sandbox="allow-scripts allow-same-origin"加在跨域 iframe 上 →allow-same-origin被浏览器静默忽略,但暴露配置疏漏,且可能被用于试探信任边界 -
sandbox="allow-scripts"却期望读取父页localStorage→ 不可能,沙箱下存储上下文完全隔离,返回空对象或抛SecurityError - React/Vue 中用
v-html或dangerouslySetInnerHTML渲染含 iframe 的 HTML → 容易漏掉sandbox属性,导致意外全开
金融/支付类 iframe 的底线配置
在收银台、身份认证等高敏场景,sandbox="allow-scripts allow-forms" 是安全与可用的平衡点:
-
allow-scripts:支撑支付宝 JS-SDK、微信 JSSDK 初始化和签名逻辑 -
allow-forms:允许用户填写银行卡号、CVV 后提交(仍走 CORS,不会发到父域) - 不加
allow-popups:防钓鱼跳转仿冒银行页 - 不加
allow-same-origin:避免 iframe 读取父页 session token - 通信必须走
window.parent.postMessage(),且父页需严格校验e.origin,不能用"*"
真正危险的不是权限不够,而是把 allow-scripts 当成“开了 JS 就万事大吉”,忘了它只管脚本加载,不管 DOM 访问、存储、导航——这些都得单独评估、单独放行,而且每多一个 allow- 前缀,攻击面就扩大一分。



















