window.opener方法的调用

本文通过一个示例展示了如何在Chrome浏览器中实现主窗口与弹出子窗口之间的交互,包括子窗口向主窗口传递返回值的过程。该示例采用纯JavaScript编写,不依赖任何前端框架。

在chrome浏览器里使用必须是在项目里面

main.html代码

<!DOCTYPE html>
<html>
<head>
	<title>main</title>
	<meta charset="utf-8">
<script language="javascript" type="text/javascript">
  var wd;
  var winTimer;//计时器变量, 监听窗口关闭 
  function openWindow() {
        wd = window.open("child.html",null," height=300,width=450,  Left=300px,Top=20px, menubar=no,titlebar=no,scrollbar=no,toolbar=no, status=no,location=no");
        if (wd){
          window.wd.focus();//判断窗口是否打开,如果打开,窗口前置  
          winTimer=window.setInterval("wisclosed()",500);
        }

  }
  function wisclosed(){
    if(wd.closed){  
      alert(window.returnVaule);//子窗体返回值  
      //这里可以做赋值操作  
      window.clearInterval(winTimer);  
    }  
  }
 </script>
</head>
<body>
	<input type="button" id="btnShow" onclick="openWindow();"  value="显示子窗口"/>
</body>
</html>
child.html代码

<!DOCTYPE html>
<html>
<head>
	<title>child</title>
	<meta charset="utf-8">
<script language="javascript" type="text/javascript">
   function doclose() {
    window.opener.window.returnVaule="ok";  
    parent.window.close(); 
  }
</script>
</head>
<body>
 <input type="button" id="btnSelect" onclick="doclose();"  value="关闭"/> 
</body>
</html>


<think>好的,用户问的是在子界面中是否应该添加判断是否来自父界面的代码,比如使用`if (window.opener && !window.opener.closed)`。用户可能已经注意到在之前的回答中,我建议使用这个条件来检查窗口的来源,但用户现在想确认是否应该这样做。 首先,我需要回顾之前的回答。用户之前的问题是关于如何让子界面在非父界面打开时跳过`postMessage`相关的代码。我的解决方案是创建一个工具函数`isOpenedByParent()`,其中使用了`window.opener && !window.opener.closed`的判断。用户现在可能是在确认这个判断是否正确,或者是否有遗漏。 用户的问题可能涉及几个方面:这个判断是否足够?是否存在其他情况需要考虑?比如,如果父窗口存在但未定义特定属性,或者子页面被嵌入到iframe中而不是通过`window.open`打开的,这时候`window.opener`可能为null,这时候如何处理? 接下来,我需要分析这个判断的有效性。`window.opener`属性返回打开当前窗口的窗口对象。如果当前窗口未被其他窗口打开,则返回null。`window.opener.closed`检查父窗口是否已经关闭。因此,`if (window.opener && !window.opener.closed)`确实可以判断当前窗口是否是由另一个窗口打开的,并且父窗口仍然处于打开状态。 但用户可能想知道是否有其他方法来确认来源,比如检查URL参数,或者是否有其他情况需要考虑,例如跨域问题。例如,如果父窗口和子窗口不同源,访问`window.opener`可能会受到限制,这时候可能需要其他方法。 另外,用户可能担心如果子页面被直接访问或者通过其他方式打开(如链接点击),如何确保代码的健壮性。这时候,除了检查`window.opener`之外,可能还需要结合其他方法,如URL参数中的标识,来确保更准确的来源判断。 此外,用户可能关心如何处理不同情况下的通信机制,例如当子页面被嵌入到iframe中时,使用`window.parent`而不是`window.opener`。这时候可能需要同时检查`window.opener`和`window.parent`,根据不同的情况选择不同的通信方式。 总结来说,用户希望确认当前的判断是否足够,或者是否需要补充其他条件。我需要解释这个判断的有效性,同时指出可能的扩展情况,如跨域、不同嵌入方式等,并提供相应的解决方案建议。 在回答时,应该先确认用户当前的判断是正确的,然后指出可能的扩展情况,并给出改进建议,比如添加URL参数检查,或者处理iframe嵌入的情况。同时,需要保持回答简洁,符合用户之前的技术栈(Vue.js,axios等),并给出代码示例。 </think>是的,你提到的 `if (window.opener && !window.opener.closed)` 是判断子页面是否由父页面通过 `window.open` 打开的标准方式。这个判断非常关键,可以避免以下问题: --- ### ✅ **为什么需要这个判断?** 1. **防止空引用错误** - 如果子页面直接通过地址栏访问(非父页面打开),`window.opener` 为 `null`,直接调用 `window.opener.postMessage(...)` 会抛出异常。 - 通过 `if (window.opener)` 可确保 `window.opener` 存在后再调用方法。 2. **防止操作已关闭的父窗口** - 如果父窗口已被用户关闭,`window.opener.closed` 会返回 `true`,此时调用 `postMessage` 会失败。通过 `!window.opener.closed` 可确保父窗口仍处于活动状态。 3. **避免跨域问题** - 如果父窗口和子窗口不同源(跨域),浏览器会限制对 `window.opener` 的访问(如 `window.opener.location` 会抛出错误)。虽然 `postMessage` 本身支持跨域通信,但需要额外处理。 --- ### 🔁 **完整判断逻辑示例** 在子页面中,所有涉及 `window.opener` 的操作都应包裹在以下条件中: ```javascript if (window.opener && !window.opener.closed) { window.opener.postMessage('closeIframe', '*') } ``` #### 🔧 **应用场景** 1. **提交操作后关闭 iframe** ```javascript function finish() { // ...其他逻辑 if (window.opener && !window.opener.closed) { window.opener.postMessage('closeIframe', '*') } closePage() } ``` 2. **退回/驳回操作后通知父页面** ```javascript function back() { // ...其他逻辑 if (window.opener && !window.opener.closed) { window.opener.postMessage('closeIframe', '*') } closePage() } ``` 3. **转交操作后通知父页面** ```javascript function transfer(userStrList) { // ...其他逻辑 if (window.opener && !window.opener.closed) { window.opener.postMessage('closeIframe', '*') } closePage() } ``` --- ### 🌐 **跨域场景的补充处理** 如果子页面和父页面存在跨域问题(如不同域名),需确保以下几点: 1. **明确指定目标域名** - `postMessage` 的第二个参数应指定目标域名(而非 `'*'`),避免安全风险: ```javascript window.opener.postMessage('closeIframe', 'https://parent-domain.com') ``` 2. **父页面监听消息并验证来源** - 父页面需监听 `message` 事件并检查 `event.origin`: ```javascript window.addEventListener('message', (event) => { if (event.origin !== 'https://child-domain.com') return if (event.data === 'closeIframe') { // 执行关闭 iframe 的逻辑 } }) ``` --- ### 📌 **其他来源判断方式** 如果子页面可能通过 iframe 嵌入(而非 `window.open`),需使用 `window.parent` 而非 `window.opener`: ```javascript if (window.parent && window.parent !== window) { window.parent.postMessage('closeIframe', '*') } ``` --- ### ✅ **总结** - **必须使用 `if (window.opener && !window.opener.closed)`**:确保子页面由父页面打开且父页面未关闭。 - **跨域场景需指定目标域名**:避免安全漏洞。 - **iframe 嵌入场景使用 `window.parent`**:区分不同的嵌入方式。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值