结论:最终完美的解决方案,删掉页面的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关闭的场景:
在这里插入图片描述

更多推荐