子页面通过window.parent.postMessage向父页面发送消息,需指定精确targetOrigin并由父页监听message事件且校验event.origin,否则消息静默丢失或存在安全风险。

子页面调用 window.parent.postMessage 发送数据
iframe 子页面要向父页面传值,必须通过 window.parent.postMessage 主动发起。不能依赖自动同步或 DOM 访问——同源策略下直接读写 window.parent 属性会报错,跨域时更完全不可行。
关键点是:子页面的 JS 运行在自己的上下文里,window.parent 指向的是嵌入它的父窗口,只要拿到这个引用,就能发消息。
-
message参数支持任意可序列化结构(对象、数组、字符串、数字),不推荐传函数或 DOM 节点 -
targetOrigin必须写具体协议+域名+端口(如"https://example.com"),绝不要用"*"上生产环境——它会让任何站点都能向你的父页发伪造消息 - 发送前建议加
try/catch,因为若父页未监听或 iframe 尚未加载完成,postMessage本身不会报错,但消息会静默丢失
父页面必须监听 message 事件并校验 event.origin
父页不主动监听,子页发再多消息也无人接收。监听本身很简单,但漏掉来源校验就等于打开安全缺口。
常见错误是只检查 event.data.type,却忽略 event.origin。攻击者可以构造恶意 iframe,用相同结构体伪造消息触发业务逻辑(比如模拟“支付成功”)。
立即学习“前端免费学习笔记(深入)”;
- 校验必须严格匹配父页信任的子源,例如只接受
"https://widget.example.net",拒绝"https://evil.com"或任何带端口变动的变体 -
event.source可用于后续回传(比如父页响应子页请求),但首次接收时不应依赖它做权限判断 - 如果父页需多次与不同子 iframe 通信,建议在
event.data中带上唯一标识(如iframeId),避免消息混淆
子页面发消息时机:确保 contentWindow 可用且父页已就绪
子页面 JS 执行时,父页可能尚未绑定 message 监听器,或者 iframe 自身还没完成加载(尤其 src 是动态设置的)。这时发消息大概率被丢弃。
- 简单做法:在子页
window.onload或DOMContentLoaded后延时 100ms 再发,给父页留出监听注册时间 - 更健壮的做法:子页先发一个
ping类型探测消息,父页收到后立即回一个pong;子页用Promise等待响应,超时则重试或报错 - 避免在子页
script标签内立即调用postMessage,尤其是未包裹在任何生命周期钩子里时——此时父页监听器几乎肯定未挂载
调试时注意 event.source 和控制台跨域限制
Chrome/Firefox 控制台默认不显示跨域 iframe 的 console 日志,你可能在子页写了 console.log 却看不到输出,误以为代码没执行。这不是 postMessage 的问题,而是 DevTools 的显示策略。
- 用
debugger断点比靠日志更可靠;或在子页加alert(仅调试)确认执行流 - 检查 Network 面板里的
Other分类,有时能看到message事件触发痕迹(非所有浏览器都显示) -
event.source在父页监听回调里可用,但它指向子窗口对象——父页可通过它调用子页方法(仅限同源子页),跨域时该引用存在但无法调用其方法
targetOrigin 的精确性与 event.origin 校验的一致性。两者必须镜像匹配,差一个斜杠、端口或协议都会导致消息被浏览器丢弃,且无任何错误提示。



















