rel=noopener标签虽小,可能对不懂开发的很多人来说对noopener标签了解的不很多,但他在维护window.opener的安全上有重大作用。
window.opener 属性是一个可读可写的属性,可返回对创建该窗口的 window 对象的引用。例如: window.opener.close()将关闭源(父)窗口。但a链接需要有 target=_blank才会有这个问题。因为没有target=_blank就不存在源(父)窗口。
关于window.opener
window.opener 表示打开当前窗体页面的的父窗体是谁。
例如,在 a 页面中,通过一个带有 target=_blank 的 a 标签打开了一个新的页面 b,那么在 b 页面里,window.opener 的值为 a 页面的 window 对象。
无来源的打开的页面,或者被禁止了 opener 的页面创建/打开,opener 的值为 null。
一般来说,打开同源(域名相同)的页面,不会有什么问题。但对于跨域的外部链接来说,存在一个安全上的风险。
在跨域的情况下,window.opener 拿不到来源页面的具体内容,但是 window.opener.location 却是例外。它会带来什么问题呢?
举个栗子:
因为如前面所讲,在新打开的页面(baidu)中可以通过window.opener获取到源页面的部分控制权,即使新打开的页面是跨域的也照样可以(例如 location 就不存在跨域问题),
那么你就让用户暴露在一个非常简单的危险境地。
第三方网站可以通过window.opener来操作源页面,会有很大的安全隐患,比如:
if (window.opener) {
window.opener.location = **网站地址**?referrer=+document.referrer;
}
复制代码第三方网站就可以更改源页面的地址源,你本来浏览的是自己的网站,点击了这个链接后,第三方的一个操作,你的页面就变成了第三方给你设置的网站了,就如上边举得那个栗子。
所以为了限制 window.opener的访问行为,为了安全起见,原始页面需要在每个使用了target=_blank的链接中加上一个rel=noopener属性,规定禁止新页面传递 rel=noopener,通过设置了此属性的链接打开的页面,其 window.opener 的值为 null。但该属性在 chrome 49+,opera 36+ 版本中才得到支持。在不支持 rel=noopener 属性的浏览器中,可以使用 rel=noreferrer 禁用 http 头部的 referer 属性跟踪来源页面,得到的效果一样。
这样网站会阻止不法者者获取有关链接源和与 referrer 链接相关的任何数据的信息。可以有效的防止打开的子页面操控源页面跳转到另一个相似的违法网站,提高网站安全性。