重新认识 window.open()

本文最后更新于:2023年8月7日 凌晨

window.open的返回值

重新认识一下这个函数window.open(url, ``*windowName, windowFeatures)*

执行window.open函数,我们可以打开一个新的标签页

其实,它是有返回值的,它返回新窗口的引用**WindowProxy**

通过返回值这个新窗口的引用,我们可以做一些符合同源策略的操作

If the window couldn’t be opened, the returned value is instead null. The returned reference can be used to access properties and methods of the new window as long as it complies with Same-origin policy security requirements.

那么,我们可以这么操作(A标签页下通过window.open打开B标签页):

  • A和B标签页同源的情况下,在A标签页通过新窗口引用操作B的localStorage

img

  • A和B标签页不同源的情况下,在A标签页通过新窗口引用操作B的localStorage

img

学到了学到了,但是好像并没有什么用…

尝试一下改变location你会发现标签页进行了跳转。

img

window.opener

上面讲的是「父标签页」操作「子标签页」,这里讲的就是相反的。

标签页在打开的时候会在window.opener存着对父标签页的引用

跟前面所讲到的一样,通过引用可以执行一些操作,比如修改父标签页的location达到重定向的效果

如果window.open打开的是一个恶意网址B,B修改A的location,就可以偷偷的把你的A转到钓鱼网址

多种打开新标签页的方式

  1. 带上_blank属性
1
<a href="https://www.feishu.cn/" target="_blank">打开新的标签页</a>
  1. 带上_blank 属性并且带 opener
1
<a href="https://www.feishu.cn/" rel="opener" target="_blank">打开新的标签页</a>
  1. 带上 _blank 属性并且带noopener
1
<a href="https://www.feishu.cn/" rel="noopener" target="_blank">打开新的标签页</a>
  1. window.open() 且不清除 opener 的值
1
2
3
4
5
6
<span class="link" onclick="openNewTabWithOpener()">打开新的标签页</span>

// js
function openNewTabWithOpener(){
window.open("真实地址");
}
  1. window.open()后再清除 opener
1
2
3
4
5
6
7
8
<span class="link" onclick="openNewTabWithoutOpener()">打开新的标签页</span>

// js
function openNewTabWithoutOpener(){
window.open("");
window.opener = null;
window.location = "真实地址";
}
  1. window.open()时带 noopener属性
1
2
3
4
5
6
<span class="link" onclick="openNewTabWithoutOpener()">打开新的标签页</span>

// js
function openNewTabWithoutOpener(){
window.open("真实地址","_blank","noopener")
}

noopener一定要加上吗?

  1. chrome88版本对超链接的rel默认设置为noopener

舒舒服服,默认就有,不用加了

  1. chrome89版本noopener终止clone sessionStorage

要是登录态存在session,那noopener打开一个相同网址的标签页就要重新登录

上述新标签页打开方式3和6就受这条更新的影响

所以,noopener并不是随便加的。在不确认新链接指向哪的时候,加上noopener比较稳妥;而在明确的可信链接指向下,加不加就看心情。

但是需要注意,由于chrome89版本的这一特性,标签页使用a标签还需要考虑加上rel="opener"

补充

在代码中执行window.open经常会被浏览器或者是一些插件认为上不友好的行为,然后被拦截

想起被弹窗广告支配的时代吗?

怎么优雅地用JavaScript打开一个新标签页?

新建一个**<a>**并加上**noopener**属性,再触发点击

1
2
3
4
5
6
7
8
9
10
<span class="link" onclick="openNewTab()">打开新的标签页</span>

// js
function openNewTab(){
const link = document.createElement("a");
link.href = "真实地址";
link.rel = "noopener"; // 这个视情况决定
link.target = "_blank";
link.click();
}

当然,除了noopener这一属性外,还有noreferrer属性来设置新标签页请求的referer


重新认识 window.open()
https://chanx.tech/2021/55a7ff847dee/
作者
ischanx
发布于
2021年8月15日
更新于
2023年8月7日
许可协议