浏览器同源策略强制拦截跨域 iframe 的 contentwindow 等访问,必须用 postmessage 通信;接收端须严格校验 event.origin 全匹配,发送前检查 contentwindow 是否存在,敏感数据需业务层加密,回传必须用 event.source 和 event.origin。

为什么不能直接访问跨域 iframe 的 contentWindow
浏览器同源策略会直接拦截任何对 iframe.contentWindow、iframe.contentDocument 或 window.parent 的读写操作。一旦跨域,哪怕只是执行 iframe.contentWindow.postMessage 之前没判空,或尝试读 iframe.contentWindow.location,都会抛出 SecurityError: Blocked a frame with origin "https://a.com" from accessing a cross-origin frame.。这不是配置能绕过的,是强制行为。
postMessage 必须校验 event.origin,否则等于裸奔
很多团队只写 postMessage(data, targetOrigin) 就以为安全了,结果上线后被钓鱼页面伪造消息触发 XSS。关键点在于接收端必须严格比对来源:
- 用全匹配(
event.origin === 'https://pay.gateway.io'),别用includes('gateway.io'),否则evil-gateway.io也能通过 - 发送端的
targetOrigin也不能写'*',尤其涉及支付、登出等敏感操作;生产环境必须写明确协议+域名+端口,比如'https://b.com:8080' - 如果子页面部署在多个子域(如
app.b.com、api.b.com),需自行封装白名单数组校验逻辑,不能依赖模糊匹配
如何防止消息发出去却石沉大海
postMessage 静默失败是高频坑点:不报错、不提示、数据就是收不到。原因通常是以下任一条件未满足:
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
-
iframe元素尚未加载完成,contentWindow为null—— 必须监听load事件,而不是DOMContentLoaded -
targetOrigin和子页面实际location.origin不一致(比如子页开了 HTTPS 重定向,但你写了 HTTP) - 子页面没注册
message监听器,或监听器里提前return了没走到处理逻辑
建议在父页发消息前加一层存在性检查:if (iframe.contentWindow) { iframe.contentWindow.postMessage(...); }
要不要给 data 字段加密
postMessage 本身不加密,也不提供传输层保护。所谓“加密”是业务层责任:
- 敏感字段(如用户 token、订单 ID)不要明文塞进
data,至少做 base64 + 签名,或走 AES 加密(密钥由主应用动态下发) - 避免把完整用户信息对象直接传过去,按需裁剪字段,遵循最小权限原则
- 不要依赖
event.source做身份认证——它可被伪造;真正可信的只有event.origin校验结果
最易被忽略的一点:子 iframe 收到消息后,若要回传响应,必须用 event.source.postMessage(reply, event.origin),而不是硬编码目标源——来路变了,回路也得跟着变。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










