金融支付场景必须用 sandbox 且配置为 sandbox="allow-scripts allow-forms",因空 sandbox 会导致白屏不可用,而该底线配置仅允许脚本执行和表单提交,禁用高危能力,并强制 origin 为 null 使 localstorage 和 cookie 失效,通信须通过严格校验 origin 的 postmessage 实现。

为什么金融支付场景必须用 sandbox,且不能只写 sandbox
因为金融支付 iframe(如收银台、身份认证页)一旦被注入恶意脚本,攻击者可劫持表单、伪造点击、窃取 token 或静默重定向——而空 sandbox 属性(即 <iframe sandbox></iframe>)会直接导致页面白屏或 net::ERR_BLOCKED_BY_RESPONSE,连基础渲染都失败。这不是“更安全”,是彻底不可用。
sandbox="allow-scripts allow-forms" 是支付 iframe 的底线配置
仅允许脚本执行和表单提交,但其他高危能力全部锁死:
-
allow-scripts:让支付 SDK(如支付宝 JS-SDK、微信 JSSDK)能初始化、签名、调起支付弹窗 -
allow-forms:使用户填写的银行卡号、CVV、有效期等字段可正常提交(注意:提交仍走 CORS,不会自动发到父域) - 不加
allow-same-origin:防止 iframe 读取父页 localStorage 中的 session token 或用户 ID - 不加
allow-popups:禁用window.open(),避免钓鱼跳转到仿冒银行页 - 不加
allow-top-navigation:杜绝top.location = 'https://phishing.com'全页劫持
跨域支付 iframe 中 localStorage 和 document.cookie 本质不可用
即使加了 allow-scripts,沙箱 iframe 的 origin 被强制设为 "null",所有存储 API 都绑定到一个临时、无持久化、父页完全不可见的上下文:
-
localStorage.setItem('token', 'xxx')不报错,但刷新后丢失,DevTools 的 Application 面板显示为空或(inactive) -
document.cookie读写均无效,且父页 cookie 不会透传进来 - 想存支付状态?必须由父页通过
postMessage接收并托管,且严格校验event.origin是否为可信域名(如https://pay.bank.com)
真要调用父页支付回调接口,别开 allow-same-origin,改用 postMessage 双向校验
常见错误是给跨域支付 iframe 加 allow-scripts allow-same-origin,以为就能调 window.parent.paySuccess()——但浏览器会静默忽略 allow-same-origin(因实际 src 与父页不同源),既没获得权限,又暴露配置疏忽。
- 正确做法:子页支付完成后,调用
window.parent.postMessage({ type: 'pay_result', data: { status: 'success', order_id: '123' } }, 'https://yourdomain.com') - 父页监听时必须显式比对
e.origin === 'https://pay.bank.com',拒绝'*' - 子页若无法修改(如银行方不提供 postMessage 支持),则支付结果需走服务端异步通知,前端只轮询订单状态
allow- token,就多一条可能被利用的攻击路径;真正关键的是把通信逻辑从 DOM 直接访问,切换到受控的 postMessage 边界上。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











