postmessage发送方必须等待iframe加载完成再调用,否则contentwindow可能为null导致消息静默丢失;接收方须严格校验event.origin并验证event.source,targetorigin不可用"*",须指定完整协议+域名+端口。

postMessage 发送方必须等 iframe 加载完成再调用
直接在 iframe 元素创建后立刻调用 contentWindow.postMessage(),大概率失败——因为 contentWindow 此时可能还没初始化,或目标页面尚未执行 JS。浏览器不会报错,但消息静默丢失。
正确做法是监听 iframe.onload 或更稳妥的 iframe.addEventListener('load', ...)。注意:如果目标页是空 HTML(比如只有 ),load 事件仍会触发;但如果目标页重定向、报 404 或 JS 报错阻塞,load 可能不触发或延迟。
- 不要依赖
setTimeout等固定延时,不同网络/设备下不可靠 - 若 iframe 源是 data URL 或
about:blank,load事件行为不一致,建议改用DOMContentLoaded在子页面内主动通知父页 - 发送前务必检查
iframe.contentWindow是否为有效对象(非null、非undefined)
接收方必须验证 event.origin,不能只信 event.data
event.origin 是唯一可被浏览器强制校验的字段,但它仍可能被恶意 iframe 伪造(尤其当父页允许 * 时)。仅靠 if (event.origin === 'https://trusted.com') 不够安全。
真正可信的是 event.source 引用本身——它指向实际发送消息的窗口对象,且无法被伪造。生产环境应组合使用:
- 先比对
event.origin是否在白名单内(如['https://a.com', 'https://b.com']) - 再向
event.source发送一条握手消息(如{ type: 'handshake', nonce: Date.now() }),要求对方回传相同nonce - 发送方设置超时(如 3s),未收到响应则丢弃后续消息
跳过这步,攻击者可在 iframe 中伪造任意 event.data 内容,触发 XSS 或越权操作。
targetOrigin 不能写成 "*",否则 Chrome/Firefox 会静默丢弃
从 2025 年起,主流浏览器(Chrome 128+、Firefox 125+)对 targetOrigin 为 "*" 的 postMessage() 调用做了严格限制:若目标窗口跨域,消息直接被丢弃,且不抛异常、不触发任何回调。
这不是 bug,是安全策略升级。你看到“发了但没收到”,八成是这里错了。
- 必须写成完整协议+域名+端口,例如
"https://api.example.com:8080" - 端口不能省略(
http://localhost和http://localhost:8080是不同源) - 开发时可用
"http://localhost:3000",但上线前必须替换为真实生产域名 - 如果目标页支持多子域(如
a.example.com、b.example.com),需分别指定,不能用通配符
message 事件监听必须在 window 上注册,且不能漏掉 event.source
接收方写 document.addEventListener('message', ...) 是无效的——message 事件只在 window 对象上触发。另外,很多示例代码忽略 event.source,导致无法回复。
典型错误是把 event.source 当作一次性引用缓存起来复用,但窗口刷新/跳转后该引用立即失效。每次收消息都应基于当前 event.source 回复:
- 正确:
event.source.postMessage('ack', event.origin) - 错误:
const cachedSource = event.source; ... cachedSource.postMessage(...)(下次消息来时 cachedSource 可能已关闭) - 如果要维持长连接,需在每次消息中携带 session ID,并由接收方主动维护 source 映射表
最常被忽略的点:子页面监听 message 时,若父页在子页 JS 执行前就发了第一条消息,这条消息会丢失——所以子页也应尽早绑定监听器(比如放在 <script></script> 标签最顶部,或 DOMContentLoaded 回调里)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











