HTML5中跨域iframe通信需严格验证双向源、结构化传数据:父页等iframe加载完成再发消息,指定targetOrigin而非"*",子页校验event.origin和event.source,双方用event.origin回传并校验字段与类型。

要在HTML5中通过postMessage实现跨域 iframe 间的安全数据交换,核心不是“能不能通”,而是“谁发给谁、发什么、怎么验、怎么回”。整个流程必须围绕双向源验证和结构化数据传递展开,缺一不可。
明确通信角色与加载时机
父页面(如 https://a.com)需嵌入子 iframe(如 https://b.com/child.html),且必须等 iframe 完全加载后才能调用 contentWindow.postMessage()。否则会因 contentWindow 未就绪而报错。
- 使用
iframe.onload或iframe.addEventListener('load', ...)确保加载完成 - 避免在 DOMContentLoaded 阶段就尝试发送——此时 iframe 可能尚未初始化 JS 上下文
- 动态创建的 iframe(如
document.createElement('iframe'))同样需监听 load 事件
发送消息时严格指定 targetOrigin
调用 postMessage(data, targetOrigin) 时,第二个参数绝不能设为 "*"(除非本地调试且无敏感逻辑)。生产环境必须写明目标源,例如 "https://b.com" 或 "https://b.com:8080"。
- 浏览器仅当目标窗口 origin 匹配该值时才投递消息,不匹配则静默丢弃
- 若子页面部署在多个子域(如
app.b.com、api.b.com),可传入数组做白名单校验(需自行封装逻辑) - 传输对象建议先用
JSON.stringify()序列化,兼容 IE9– 及部分旧内核
接收方必须验证 event.origin 并限定 source
子页面通过 window.addEventListener('message', handler) 接收消息,但 handler 内第一件事是校验来源:
立即学习“前端免费学习笔记(深入)”;
- 检查
event.origin === 'https://a.com',不匹配立即 return - 避免只校验域名(如
event.origin.includes('a.com')),防止evil-a.com伪造 - 必要时进一步比对
event.source是否为预期的父窗口(如event.source === window.parent) -
event.data需做类型与字段校验(如是否含type字段、data是否为对象),防恶意构造
支持双向响应与错误隔离
安全通信不是单程快递,而是可追溯的对话链。子页面收到合法消息后,应使用 event.source.postMessage(reply, event.origin) 回复,且 reply 中建议携带唯一 id 或 timestamp 便于父页面识别上下文。
- 回复时也必须用
event.origin而非硬编码,确保回传路径与来路一致 - 对异常消息(如非法 JSON、缺失关键字段)不响应,也不抛出可被外部捕获的错误
- 可在父页面为每次发送设置超时定时器,未在预期时间内收到 reply 则主动清理状态



















