跨域 iframe 通信必须用 postMessage,发送前需确保 iframe 加载完成并指定精确目标源;接收方须严格校验 event.origin,响应需带唯一 ID 并实现超时控制。

iframe.contentWindow.postMessage 发送跨域消息
直接访问跨域 iframe 的 window 或 document 会触发安全错误,必须用 postMessage。发送方调用 iframe.contentWindow.postMessage(),第一个参数是任意可序列化的数据,第二个参数是目标源(不能写 *,必须明确协议+域名+端口)。
-
iframe必须已加载完成(监听load事件后再发),否则contentWindow可能为null - 目标源写错(比如漏了
https://、端口不匹配、用了*)会导致消息静默丢弃,控制台无报错 - 若 iframe 来自同域,也可用
postMessage,但此时接收方可省略源校验(不推荐)
const iframe = document.getElementById('myIframe');
iframe.addEventListener('load', () => {
iframe.contentWindow.postMessage({ type: 'INIT', data: 'hello' }, 'https://remote.example.com');
});
监听 message 事件并校验 origin
接收方在 window 上监听 message,关键在验证 event.origin —— 这是浏览器自动注入的发送源,不可伪造。切勿只校验 event.source 或信任 event.data 里的字段。
-
event.origin格式严格为https://domain.com:port,不含路径;本地文件用file://时值为null(需特殊处理) - 多个 iframe 可能同时发消息,建议用
event.source === iframe.contentWindow做双向绑定校验(尤其当页面含多个跨域 iframe) - 避免直接执行
event.data中的函数字符串或eval,应只解析结构化数据
window.addEventListener('message', (event) => {
if (event.origin !== 'https://remote.example.com') return;
if (event.data.type === 'INIT') {
console.log(event.data.data); // 'hello'
}
});
postMessage 回调与响应机制怎么设计
原生 postMessage 是单向的,如需响应,双方需约定唯一 id 字段 + 回调标识。常见做法:发送方生成随机 id,接收方收到后用同一 id 回复到 event.source。
-
event.source指向发送方的window对象,可直接用于回复,无需再存引用 - 不要依赖
event.ports(仅用于Channel Messaging,且跨域 iframe 不支持) - 超时控制必须由应用层实现:发送方设
setTimeout,接收方响应时清除定时器
// 发送方(父页)
const msgId = Date.now() + '-' + Math.random().toString(36).substr(2, 9);
const timeout = setTimeout(() => console.error('timeout'), 5000);
window.addEventListener('message', function onReply(event) {
if (event.data.id === msgId && event.origin === 'https://remote.example.com') {
clearTimeout(timeout);
window.removeEventListener('message', onReply);
console.log('reply:', event.data.payload);
}
});
iframe.contentWindow.postMessage({ id: msgId, type: 'GET_DATA' }, 'https://remote.example.com');
iframe 加载失败或未就绪时的容错处理
跨域 iframe 加载失败(如 404、CORS 阻止、网络中断)时,load 事件不触发,contentWindow 可能为 null 或抛出跨域异常。无法通过 onerror 捕获 iframe 资源错误(浏览器限制)。
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
立即学习“Java免费学习笔记(深入)”;
- 设置
iframe的src后,立即检查iframe.contentWindow是否存在;若为null,说明尚未加载或被拦截 - 可用
iframe.onload和iframe.onerror组合判断:虽然onerror对跨域资源不总触发,但对同域 fallback 页面有效 - 更可靠的方式是让子页面主动通知父页“已就绪”——子页加载完立即
postMessage({ type: 'READY' }),父页监听并设状态标志
跨域通信不是“连上就通”,而是“每次消息都要校验、每次响应都要防丢”。最常被忽略的是源校验的严格性和超时兜底——没有这两条,线上出问题时几乎无法定位。









