加了sandbox却JS不执行、按钮点不动,是因为sandbox默认全锁死:脚本、表单、弹窗、localStorage、内联事件(如onclick)均被静默拦截,控制台不报错;必须显式设置最小权限,如sandbox="allow-scripts"仅解禁外链脚本,内联事件仍需改用addEventListener绑定。

iframe 加了 sandbox 却 JS 不执行、按钮点不动?
不是 bug,是 sandbox 默认锁死全部能力。空值 sandbox="" 或只写 sandbox 会禁用脚本、表单、弹窗、localStorage、内联事件(如 onclick)——浏览器静默拦截,控制台不报错。
必须显式放行最小必要权限:
-
sandbox="allow-scripts":仅允许 JS 执行,但onclick="doX()"仍无效;所有交互逻辑得改用addEventListener绑定 -
sandbox="allow-scripts allow-forms":支持表单提交,但提交目标仍受 CORS 控制 -
sandbox="allow-scripts allow-popups":允许window.open(),适合图表导出、缩放等场景 - 绝对避免
allow-same-origin,除非 iframesrc与父页协议+域名+端口完全一致,且服务端已配好SameSitecookie 和Access-Control-Allow-Origin
postMessage 发消息总收不到?
常见原因是 iframe.contentWindow 为 null 或 targetOrigin 写错。跨域 iframe 动态插入后,contentWindow 不是立即可用的。
正确做法:
立即学习“前端免费学习笔记(深入)”;
- 必须监听
load事件后再调用postMessage,不能靠setTimeout或 DOM 插入顺序猜测 -
targetOrigin参数绝不能填'*',生产环境必须精确匹配子页实际 origin,例如'https://widget.example.com:8080' - 子页接收时只信
event.origin,且必须用===严格比对,includes('example.com')可被https://evil-example.com绕过 - Chrome 117+ 会丢弃非结构化数据:传
new Date()、正则、函数,接收端得到undefined;只传 plain object
iframe 加载就空白或控制台报 Refused to frame?
不是前端代码问题,是服务端安全头或父页 CSP 拦截了。
分两类排查:
- 目标页面返回了
X-Frame-Options: DENY或Content-Security-Policy: frame-ancestors 'none'→ 前端无法绕过,只能换官方 widget、oEmbed 或后端代理解析 - 父页 CSP 中
frame-src未授权目标域名 → 需在响应头中明确添加,例如frame-src 'self' https://maps.google.com; - HTTPS 页面加载 HTTP iframe → 触发混合内容拦截,必须全站 HTTPS
SPA 路由切换后 iframe 还在后台跑?
iframe 生命周期不随 Vue onUnmounted 或 React useEffect cleanup 自动结束。子页的 setInterval、WebSocket、window.addEventListener('message', ...) 全部继续运行,且无法被 GC 回收。
销毁前必须手动清理:
- 先向子页发通知消息,让其主动卸载逻辑(如有)
- 再调用
iframe.contentWindow?.close() - 最后
iframe.remove()或从 DOM 移除节点 - 不要只删 DOM 就认为子应用已退出——JS 上下文仍在内存里
postMessage 不是可选通信方式,是唯一合规通道;而 iframe 的销毁,从来不是移除 DOM 那么简单。



















