子页面读取 window.parent 前必须确保同源,父页变量需显式挂载到 window 对象,子页读取须加存在性判断并延后执行,跨域时唯一可行方案是 postmessage 通信。

子页面直接读 window.parent 前必须确认同源
浏览器只允许协议、域名、端口三者完全一致时,子页面才能安全访问父页面的 window.parent。哪怕只是父页用 http://localhost:8080、子页用 http://127.0.0.1:8080,也会被拦截并抛出 Blocked a frame with origin ... from accessing a cross-origin frame 错误。此时任何 window.parent.xxx 都会直接报错,不是“读不到”,而是根本不可访问。
父页面变量必须显式挂到 window 上
常见错误是父页写了 const user = {id: 1} 或 let token = 'abc',子页却试图读 window.parent.user —— 这必然 undefined。JS 的块级作用域变量不会自动暴露给 iframe。
- 正确写法:在父页中明确赋值给
window,例如window.currentUser = {id: 1, name: 'admin'} - 若父页用 Vue/React 等框架,状态默认不挂
window,必须手动导出:window.appState = store.state - Layui 弹层中,
layer.open({type: 2, content: 'child.html'})后,父页 JS 执行时机可能晚于子页加载,变量未初始化就已被读取
子页面读取时要加存在性判断 + 延迟策略
子页 <script></script> 在 HTML 解析阶段就执行,但父页 JS 可能还在 DOM 加载或 AJAX 请求中。直接写 console.log(window.parent.currentUser.id) 极易报 Cannot read property 'id' of undefined。
- 基础防护:始终包裹判断
if (window.parent && window.parent.currentUser) - 更稳妥:用
DOMContentLoaded或setTimeout延后几毫秒再读,例如setTimeout(() => { /* 读取逻辑 */ }, 50) - 最佳实践:父页在
layer.open的success回调里,通过iframe.contentWindow.postMessage()主动推送数据,子页监听message事件接收
跨域场景下 window.parent 完全失效,必须换方案
一旦父子页不同源,window.parent 对象本身可访问,但它的属性和方法全部被浏览器屏蔽。你甚至不能对它做 typeof 或 JSON.stringify,一碰就报错。
- 唯一通用解法是
postMessage:父页发消息时指定targetOrigin(严禁用'*'),子页用event.origin严格校验来源 -
event.data只支持结构化克隆对象(Object/Array/Date/Boolean 等),不能传函数、DOM 节点或undefined - 消息不是可靠队列:子页监听器注册太晚,首条消息会丢失;务必在
<script></script>最顶部就绑定window.addEventListener('message', handler)
父页面变量是否挂到 window、子页面读取时机是否晚于父页初始化、跨域时是否切换通信方式——这三个点漏掉任意一个,window.parent.xxx 就会静默失败,且错误提示极其模糊。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











