在Chrome浏览器中,window.close和self.close并没有关闭窗口。

问题是,当我调用window.close()self.close()时,并没有关闭该窗口。现在似乎有一种观点认为,在Chrome中,你不能用脚本关闭任何非脚本创建的窗口。这显然是错误的,但无论如何,它仍然应该这样做,即使它需要弹出一个警报来确认。这些都没有发生。

那么,有没有人有真正的、实用的、经过验证的方法来关闭一个窗口,使用javascript:window.close()javascript:self.close(),真正做到预期的效果,并且在所有不是基于Chrome的浏览器中都能正常运行?如果有任何建议,我将非常感激,我正在寻找Javascript的具体解决方案,没有JQuery或第三方的实现。

更新:虽然很多建议都有严重的局限性和可用性问题,但最新的建议(专门针对TamperMonkey)在脚本标题中使用// @grant window.close往往会起到作用,甚至在那些通常无法处理关闭方法的标签上。虽然并不完全理想,也不能适用于每一种情况,但在我的情况下,这是一个很好的解决方案。

普通的javascript不能随意地关闭窗口。 这是一个安全功能,不久前才引入,以阻止各种恶意的利用和烦扰。

来自window.close()的最新工作规范

窗口对象上的close()方法,如果满足以下所有条件,应该关闭浏览环境A

  • 相应的浏览上下文Ascript-closable
  • 在职脚本的浏览上下文是熟悉浏览上下文A的。
  • 现任脚本的浏览上下文被允许浏览浏览上下文A

如果一个浏览上下文是由脚本创建的辅助浏览上下文(而不是由用户的动作创建的),或者如果它是一个浏览上下文,其会话历史只包含一个Document,那么这个浏览上下文就是脚本可关闭的。

这意味着,除了一个小的例外,javascript不能被允许关闭一个不是由同一个javascript打开的窗口

Chrome允许这个例外--它并不适用于用户脚本--但是Firefox不允许。 火狐浏览器的实现直截了当地指出

这个方法只允许被脚本用window.open方法打开的窗口所调用


如果你试图从Greasemonkey / Tampermonkey / 用户脚本中使用window.close,你会得到。
Firefox:错误信息,"Scripts may not close windows that were not opened by script." Chrome:只是默默地失败。



长期的解决方案。

处理这个问题的最好方法是做一个Chrome扩展和/或Firefox插件来代替。这些可以可靠地关闭当前窗口。

然而,由于window.close带来的安全风险对于Greasemonkey/Tampermonkey脚本来说要小得多;Greasemonkey和Tampermonkey可以合理地在其API中提供这一功能(基本上为你打包了扩展工作)。
考虑提出一个功能请求



棘手的变通方法。

Chrome 目前容易被"自我重定向"利用。 所以像这样的代码过去一般都能工作。

open(location, '_self').close();

这是错误的行为,IMO,现在(大约在2015年4月)大部分被阻止了。 如果标签页是新打开的,并且在浏览历史中没有任何页面,那么****的代码仍然可以发挥作用。 所以它只在很小的情况下有用。

然而,一种变体仍然可以在Chrome(v43 & v44)和Tampermonkey(v3.11或更高版本)上使用。 使用明确的@grant和普通的window.close()。EG。

// ==UserScript==
// @name        window.close demo
// @include     http://YOUR_SERVER.COM/YOUR_PATH/*
// @grant       GM_addStyle
// ==/UserScript==

setTimeout (window.close, 5000);

感谢 zanetu 的更新。 请注意,如果只有一个标签打开,这将不起作用。它只会关闭额外的标签。


火狐浏览器对该漏洞是安全的。 因此,唯一的javascript方法是削弱安全设置,一次一个浏览器。

你可以打开about:config并设置 allow_scripts_to_close_windowstrue

如果你的脚本是供个人使用的,就去做吧。 如果你要求其他人打开这个设置,他们会很聪明,而且有理由不带偏见地拒绝。

目前,Chrome浏览器还没有相应的设置。

评论(20)

我正在使用Brock Adams发布的方法,它甚至在Firefox中工作,如果它是用户发起的。

open(location, '_self').close();

我是通过按下按钮来调用它的,所以它是**用户发起的,而且它在Chrome 35-40、Internet Explorer 11、Safari 7-8和ALSO Firefox 29-35中仍然工作良好。我使用Windows的8.1版本和Mac OS X 10.6、10.9 & 10.10版本进行了测试,如果有不同的话。


自动关闭窗口代码(在页面上自动关闭)

在用户打开的窗口上使用的完整代码,可以自行关闭。

window_to_close.htm

JavaScript。

function quitBox(cmd)
{   
    if (cmd=='quit')
    {
        open(location, '_self').close();
    }   
    return false;   
}

HTML。

<input type="button" name="Quit" id="Quit" value="Quit" onclick="return quitBox('quit');" />

试试这个测试页面。(现在在Chrome 40和Firefox 35中测试)

http://browserstrangeness.bitbucket.io/window_close_tester.htm


开窗器代码(在打开上述页面的页面上)

为了使其发挥作用,安全方面的跨浏览器兼容性要求要关闭的窗口必须已经被用户在同一网站域内点击按钮打开。

例如,使用上述方法关闭的窗口,可以从一个使用此代码的页面中打开(代码由我上面链接的示例页面提供)。

window_close_tester.htm

JavaScript。

function open_a_window() 
{
    window.open("window_to_close.htm"); 

    return false;
}

HTML。

<input type="button" onclick="return open_a_window();" value="Open New Window/Tab" />
评论(6)

尽管认为这是"明显的错误",但你所说的"似乎是一种信念"实际上是正确的。Mozilla关于window.close的文档说

这个方法只允许被调用给那些由脚本用window.open方法打开的窗口。如果该窗口不是由脚本打开的,那么在JavaScript控制台会出现以下错误。脚本不能关闭不是由脚本打开的窗口

你说它应该还是会这样做的,但我不认为你能找到任何支持这种说法的参考资料,也许你记错了什么?

评论(0)