浏览器安全机制问题导致无法关闭页面 Scripts may close only the windows that were opened by them
·
结论:最终完美的解决方案,删掉页面的close关闭按钮 让用户点击浏览器tab上的关闭按钮 。


历史背景:

如何查看chrome版本:
console.log(navigator.userAgent)

window.close()` 为什么手动打开就关不掉?
根本原因:浏览器的 opener 安全策略
浏览器在允许 window.close() 之前,会检查一个条件:这个窗口是不是由脚本打开的?
判断依据是 window.opener:
- 通过
window.open()打开的页面 →opener指向父窗口 → 浏览器允许关闭 - 用户手动输入 URL / 从书签打开 →
opener为null→ 浏览器拒绝关闭,报错:
Scripts may close only the windows that were opened by them.
这是 Chrome、Firefox、Edge 都遵守的标准安全策略,无法直接绕过,目的是防止恶意网页强制关闭用户的其他标签页。
// 如下解决方案,已过时 ;Chrome 高版本已经封死这个trick
三种过时解决方案
方案一:页面加载时自我重开(适合单页面修复)
在页面 JS 最顶部加:
(function() {
if (!window.opener) {
var url = window.location.href;
var sep = url.indexOf('?') > -1 ? '&' : '?';
// 加参数避免死循环
if (url.indexOf('_reopen=1') === -1) {
window.open(url + sep + '_reopen=1', '_self');
}
}
})();
页面加载时检测 opener,若为空则用 window.open 重新打开自身,使浏览器认为这是脚本打开的窗口,后续关闭就能成功。
方案二:重写关闭函数加兜底
var _orig = ____Com_CloseWindow;
____Com_CloseWindow = function() {
_orig(); // 先走原逻辑
// 兜底关闭
try {
window.open('', '_self');
window.close();
} catch(e) {}
};
方案三:全局 JS 注入(推荐,一劳永逸)
在系统的自定义 JS 入口,所有页面自动生效:
(function() {
// 页面加载时若非脚本打开,则自我重开
if (!window.opener && window.location.href.indexOf('_reopen=1') === -1) {
var url = window.location.href;
var sep = url.indexOf('?') > -1 ? '&' : '?';
window.open(url + sep + '_reopen=1', '_self');
return;
}
// 同时重写关闭函数保底
if (typeof ____Com_CloseWindow === 'function') {
var _orig = ____Com_CloseWindow;
____Com_CloseWindow = function() {
_orig();
try { window.open('', '_self'); window.close(); } catch(e) {}
};
}
})();
// 常规方案已过期 ,科普下能被close关闭的场景:

更多推荐


所有评论(0)