说一说window.parent

本文探讨了如何使用window.parent属性来判断网页是否嵌套在iframe中,并提供了一种有效的方法来解决session超时后,需要将整个页面跳转到登录页的问题。

<iframe>标签是很常用的,嵌在页面之中,可以做独立的加载和刷新。比如说,页面分左右或者上下结构,一般左侧和上侧是导航部分,右侧和下侧是目标页面的展示部分,只需要设置导航链接的target属性等于右侧iframe的name属性即可。

有一个需求,当session超时之后,无论点击任何的链接,都要使整个页面跳转至登陆页面。

以前未接触框架的时候,一般使用过滤器Filter来实现,过滤所有的url,当然对于登陆和退出的url不进行拦截,如果session不存在就重定向至登陆页。

接触struts2之后,就是用全局拦截器,拦截符合条件的url,依然是对session进行判断,看一看session里面的信息是否符合放行的条件。

现在是springmvc,拦截器与struts2原理基本一致,只不过本项目需要考虑的东西稍微多一些而已,但本文不对拦截器进行详细阐述。主要说一说window.parent。

如本文第一段所述,点击有target的链接,页面就会指向iframe,当session超时之后,点击链接依然如此,那么iframe里的页面会跳转至登陆页,整个页面却是不动的,这样我们就需要在登陆页中判断一下,该页面是否存在父页面,如果存在就把该登陆页的url赋给父页面。

然而,window.parent总是不为空,window.parent.location也是不为空,如果直接进入登陆页(其本身没有iframe),window.parent.location就是其自身。这样就区分不出登陆页是否有父页面了?当然了,通过解析window.parent.location的不同是可以区分出来的,但是这个太低端,不是本文讨论的重点。

问题的集中点在于,登陆页它是否存在于某个iframe里面,或者他的父页面中是否存在iframe,这个如何做呢?

偶然看到window.parent.frames,这个是获得父窗口的所有集合,如果window.parent.frames.length>0说明存在iframe,否则不存在,这样可以区分出登陆页面是否嵌在iframe中。但总觉得通用性不够,依然显得低端。

仔细观察,发现window.parent依然是一个window,也就是说是一个window对象,那么window对象之间可以不可以实现比较呢?比如说:window.parent==window我们想拿它的父窗口和他的当前窗口进行比较,会不会出错呢?多说无用,试试就知道了。

1,登陆页自己alert(window.parent==window);返回true。

2,登陆页嵌在iframe中;返回false。

说明我们的猜想是正确的,没有问题,这样我们就可以区分出登陆是否存在父页面了,而且各种情况都通用。

<think>我们正在讨论跨窗口通信中的postMessage方法。根据提供的引用,我们需要确定使用window.parentWindow.postMessage还是window.parent.postMessage。 首先,查看引用: 引用[1]提到:otherWindow.postMessage(message, targetOrigin, [transfer]); 其中otherWindow是其他窗口的引用,例如iframe的contentWindowwindow.open返回的窗口对象、window.frames或父级window.parent。 引用[2]提到:一个窗口可以获得对另一个窗口的引用(比如 targetWindow = window.opener),然后在窗口上调用 targetWindow.postMessage()方法。 引用[3]提到:当使用window.parent.document.getElementById('iframeId').contentWindow.postMessage传递消息时,需要注意跨域问题。同时,建议使用window.parent.frames[name]来获取iframe元素(当同源时可以直接用window.parent.document,但跨域时不行)。 引用[4]提到:直接使用window.parent.postMessage(...)来传值。 问题:window.parentWindow.postMessage vs window.parent.postMessage 哪个正确? 分析: 1. 在标准中,并没有window.parentWindow这个属性。window对象有一个parent属性,用于返回当前窗口的父窗口(如果当前窗口是顶层窗口,则parent属性返回自身)。 2.parentWindow并不是标准属性。在早期IE浏览器中,可能支持parentWindow,但现代浏览器中,我们应使用标准属性。 因此,正确的应该是使用window.parent.postMessage。 但注意:window.parent返回的是父窗口的引用,它是一个窗口对象。我们可以直接在这个对象上调用postMessage方法。 例如,在iframe中,要向父窗口发送消息,可以这样写: window.parent.postMessage(message, targetOrigin); 而如果我们要在父窗口中向某个子iframe发送消息,则需要先获得子窗口的引用,例如: var iframe = document.getElementById('myIframe'); iframe.contentWindow.postMessage(message, targetOrigin); 所以,结论是:使用window.parent.postMessage是正确的,而window.parentWindow.postMessage是不正确的(除非你自定义了一个parentWindow变量)。 另外,引用[3]还提到,如果父子页面不同源,则不能使用window.parent.document来获取DOM元素,因为跨域限制。此时,我们可以通过window.parent.frames[name]来获取子窗口的引用(但同样,如果不同源,通过这种方式获取到的窗口引用,我们只能使用postMessage方法进行通信,而不能访问其DOM)。 因此,回答用户:应该使用window.parent.postMessage,而不是window.parentWindow.postMessage(因为后者不是标准属性,且通常不存在)。 同时,我们也可以生成相关问题来帮助用户深入理解。</think>在跨窗口通信中,正确的标准方法是使用 `window.parent.postMessage`。以下是详细分析和说明: ### 正确方法解析 1. **`window.parent` 是标准属性** - `window.parent` 是浏览器原生支持的只读属性,用于获取当前窗口的直接父窗口引用(如 iframe 的父页面)[^1][^2]。 - 语法示例: ```javascript // 从子页面向父页面发送消息 window.parent.postMessage({ data: "example" }, "https://parent-domain.com"); ``` 2. **`window.parentWindow` 不存在** - 浏览器标准中 **没有 `parentWindow` 属性**,使用该写法会导致 `Uncaught TypeError: window.parentWindow is undefined` 错误[^3][^4]。 3. **跨域通信的关键点** - 必须指定精确的 `targetOrigin`(如 `"https://target-domain.com"`),`*` 仅用于开发测试[^1][^2]。 - 跨域时禁止直接访问 DOM(如 `window.parent.document`),必须通过 `postMessage` 通信[^3]。 ### 完整使用示例 ```javascript // 子页面发送消息给父页面 window.parent.postMessage( { type: "status", payload: { loaded: true } }, "https://parent-domain.com" // 必须匹配父页面协议+域名+端口 ); // 父页面接收消息 window.addEventListener("message", (event) => { if (event.origin !== "https://child-domain.com") return; // 验证来源 console.log("Received:", event.data); }); ``` ### 常见错误场景 1. **跨域访问 DOM** ❌ 错误写法: ```javascript // 跨域时无法获取父页面DOM window.parent.document.getElementById("element"); ``` ✅ 替代方案:通过 `postMessage` 请求父页面主动操作 DOM[^3]。 2. **忽略 origin 验证** ❌ 不安全接收: ```javascript window.addEventListener("message", (event) => { // 未验证 event.origin 可能遭受XSS攻击 }); ``` ### 相关问题 1. 如何在主页面与多个 iframe 之间实现双向通信? 2. `postMessage` 传输大型数据结构时有哪些性能优化方法? 3. 使用 `postMessage` 时如何防止恶意网站窃听消息? 4. 除了 `window.parent`,还有哪些获取跨窗口引用的安全方式(如 `window.opener`)? [^1]: `otherWindow.postMessage()` 需要精确指定 `targetOrigin`,跨域通信必须验证来源。 [^2]: 通过 `window.opener` 或 `window.parent` 获取窗口引用是安全通信的前提。 [^3]: 跨域时禁止直接访问 `window.parent.document`,需改用 `postMessage` 通信。 [^4]: 实际项目中直接调用 `window.parent.postMessage` 是标准做法。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值