为何设置rel="noreferrer"时window.close跨页失效,改为rel="opener"就正常?
核心原理
浏览器对window.close()的调用有严格权限限制:只有当前窗口的上下文可以追溯到主动打开它的外部脚本/页面时,才允许脚本调用该方法关闭窗口,你看到的Scripts may close only the windows that were opened by it.警告就是权限校验不通过触发的。
两种rel属性的差异导致了不同的表现:
使用rel="noreferrer"时的表现逻辑
noreferrer除了禁止跳转时发送Referer请求头之外,还会隐式附带noopener效果:
- 站点A打开站点B首页时,B首页的窗口上下文临时持有指向站点A的
opener引用,满足权限要求,因此首页可以正常调用window.close()。 - 当站点B发生同域内部跳转时,浏览器会销毁旧页面的上下文,新建的页面上下文因为
noreferrer的限制,不会继承之前的opener引用,此时新页面的opener值为null,浏览器判定该页面不是外部脚本打开的,因此关闭方法失效。
使用rel="opener"时的表现逻辑
opener属性会显式保留新打开窗口和父窗口(站点A)的关联,且该关联会在站点B的同域跳转过程中被继承:
不管站点B内部跳转到哪个同域页面,新页面的上下文始终持有指向站点A的opener引用,始终满足权限校验要求,因此所有页面都可以正常调用window.close()关闭窗口。
内容的提问来源于stack exchange,提问作者Alee
相关产品推荐
相关产品推荐

