同源时直接操作window对象最简单,跨域时唯一可靠方案是postmessage;同源iframe可通过contentwindow、parent等属性互相调用函数和访问dom,跨域则必须用postmessage并严格校验origin。

同源时直接操作 window 对象最简单;跨域时唯一可靠方案是 postMessage,其他任何尝试(比如读 contentDocument、调用 contentWindow.someFunc)都会触发 SecurityError: Blocked a frame with origin ... from accessing a cross-origin frame。
同源 iframe 怎么直接调用对方函数
父页面能通过 iframe.contentWindow 拿到子页的全局对象,子页能用 window.parent 或 window.top 回溯父页 —— 前提是协议、域名、端口三者完全一致。
- 父页调子页:必须等
iframe.onload触发后再执行,否则contentWindow可能为null或方法未定义 - 子页调父页:函数必须挂到
window上(不能是闭包内或模块变量),例如window.parentCallback = function() {...} - 不推荐用
document.frames['name'],IE 专属且现代浏览器已弃用 - DOM 访问也一样:子页可通过
parent.document.getElementById('x')操作父页元素,但前提是同源
跨域 iframe 必须用 postMessage 发消息
浏览器禁止跨域脚本访问,postMessage 是 HTML5 唯一被所有现代浏览器支持的跨域通信机制。它不绕过安全策略,而是由浏览器代为转发并提供来源校验能力。
- 父页发消息前必须检查
iframe.contentWindow是否存在,否则报Cannot read property 'postMessage' of null -
targetOrigin参数严禁写'*',应明确指定如'https://child.example.com';否则恶意站点可伪造 origin 接收消息 - 子页监听
message事件时,必须用event.origin === 'https://parent.example.com'严格比对,不能用includes或正则 -
event.data是结构化克隆对象,支持Object、Array、Date,但不支持function、undefined、DOM node
postMessage 的时序和注册时机很关键
消息不是发了就一定被收到 —— 子页可能还没加载完,或者 message 监听器注册太晚,导致首条消息丢失。
- 父页应在
iframe.onload后再调postMessage,不能靠setTimeout猜测加载时间 - 子页必须在
script标签最顶部(或DOMContentLoaded阶段)就注册message监听器,不能等到某个按钮点击才注册 - 如果子页是单页应用(SPA),需确保路由切换后监听器仍有效,避免重复绑定或漏绑
- 父页若需等待子页响应,应设计成“发消息 + 监听子页回传”,不能假设子页会自动执行某逻辑
URL 参数传值只适合初始化,别当通信通道用
把数据拼进 iframe.src 查询参数(如 src="child.html?id=123&theme=dark")确实能绕过跨域限制,但它是一次性的,无法响应运行时变化。
- 子页只能在加载时读取
window.location.search,之后父页改参数不会触发重载或通知 - 参数长度受限(通常 2048 字符以内),不适合传大对象或二进制数据
- 敏感信息暴露在 URL 中,会被历史记录、服务端日志、代理缓存捕获
- 如果子页本身有路由(如
/dashboard?tab=1),手动拼参容易破坏原有路径结构
真正难的不是写通第一条消息,而是让通信在各种加载顺序、多实例嵌套、SPA 路由跳转、页面卸载等边界场景下依然稳定 —— 这些地方最容易漏掉 removeEventListener、没处理 event.source 失效、或误把测试环境的 '*' 用到生产。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











