window.postMessage()是最通用、兼容性最好且最安全的跨域通信方案,但必须严格校验event.origin以防XSS;父页需在iframe加载完成后通过contentWindow.postMessage发送消息,子页须验证origin并用event.source回传以确保目标准确。

直接说结论:用 window.postMessage() 是目前最通用、兼容性最好、也最安全的跨域通信方案,但必须手动校验 event.origin,否则有 XSS 风险。
父页面怎么向 iframe 子页面发消息
关键不是“能不能发”,而是“发给谁”和“发到哪”。postMessage 必须明确目标窗口引用,不能凭空调用。
- 先确保 iframe 已加载完成,再取
iframe.contentWindow,否则会是null -
iframe.contentWindow.postMessage(data, targetOrigin)中的targetOrigin建议写死,比如'https://child.com',别用'*'(开发时可临时用,上线必须改) - 如果子页面是 http 协议而父页是 https,浏览器会静默丢弃消息——协议必须一致
- 示例:
const iframe = document.getElementById('myIframe'); iframe.onload = () => { iframe.contentWindow.postMessage({ type: 'INIT', token: 'abc123' }, 'https://child.com'); };
子页面怎么接收并校验消息来源
只监听 message 事件远远不够,不校验 event.origin 就等于把门敞开给任意网站。
- 必须检查
event.origin === 'https://parent.com',不能只看域名,协议+端口都要匹配 - 不要信任
event.source做权限判断——它可能被伪造或误用 - 收到消息后,建议用
typeof event.data或event.data?.type做基础结构校验,避免undefined报错 - 示例:
window.addEventListener('message', (event) => { if (event.origin !== 'https://parent.com') return; if (typeof event.data !== 'object') return; console.log('received:', event.data); });
子页面怎么反向通知父页面
子页调用 window.parent.postMessage() 即可,但要注意:父页可能不是顶层窗口(比如嵌在多层 iframe 里),window.parent 不一定可靠。
- 更稳妥的方式是用
event.source.postMessage(),它指向发来消息的那个窗口,天然准确 - 如果子页需要主动发起通信(比如点击按钮),且不确定父页是否已监听,可以先发个探测消息,等父页回一个确认再继续
- 不要在子页 onload 里立刻发消息——父页的监听器可能还没绑定
- 示例:
document.getElementById('sendBtn').onclick = () => { // 使用 event.source 更安全 window.parent.postMessage({ type: 'USER_CLICK' }, 'https://parent.com'); };
常见错误和兼容性坑点
看似简单,实际踩坑集中在数据类型、时机、校验三块。
- IE10+ 支持对象直传,但 IE9 只认字符串——如果要兼容,统一用
JSON.stringify()+JSON.parse() -
postMessage是异步的,不能假设“发完就收到”,尤其在频繁通信场景下容易丢帧 - Chrome 和 Firefox 对
targetOrigin校验严格;Safari 在某些版本中会忽略端口差异,导致误通过 - 如果父页用
window.open()打开新窗口,需保存返回的 window 引用,不能靠window.opener反向通信(对方可能关闭或跳转)
真正难的从来不是调用那行代码,而是消息边界怎么划、谁负责超时重试、错误怎么降级、以及 origin 校验漏掉一个字符就等于放弃安全底线。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











