window.close和self.close不关闭Chrome中的窗口

时间:2013-11-04 03:33:03

标签: javascript google-chrome greasemonkey tampermonkey

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

所有人都有真实的,功能齐全且经过验证的关闭窗口的方法,使用javascript:window.close()javascript:self.close()之类的东西来实际完成所期望的事情,以及在非Chrome浏览器中发生的事情。根据?任何建议将不胜感激,我正在寻找Javascript特定的解决方案,没有JQuery或第三方实现。

更新虽然已提出的大部分内容存在严重的限制和可用性问题,但在脚本中使用 // @grant window.close 的最新建议(特定于TamperMonkey)即使在那些通常无法处理close方法的选项卡上,标题也会经常发挥作用。虽然不完全理想,并没有针对每种情况推广,但在我的情况下,这是一个很好的解决方案。

15 个答案:

答案 0 :(得分:167)

普通的javascript无法关闭Windows willy-nilly。这是一段安全功能,不久前推出,用于阻止各种恶意攻击和烦恼。

来自the latest working spec for window.close()

  

如果满足以下所有条件,则Window对象上的close()方法应关闭浏览上下文 A

     
      
  • 相应的浏览上下文 A 脚本可关闭
  •   
  • 现有脚本的浏览上下文熟悉浏览上下文 A
  •   
  • 允许现有脚本的浏览上下文导航浏览上下文 A
  •   
     

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

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

Chrome允许该异常 - 它不适用于用户脚本 - 但Firefox不支持。 The Firefox implementation flat out states

  

只允许为使用window.open方法的脚本打开的窗口调用此方法。


如果您尝试使用Greasemonkey / Tampermonkey / userscript中的window.close,您将获得:
Firefox:错误消息“Scripts may not close windows that were not opened by script.
Chrome:只是默默地失败。



长期解决方案:

处理此问题的最佳方法是改为使用Chrome扩展程序和/或Firefox附加组件。这些可以可靠地关闭当前窗口。

但是,由于window.close所带来的安全风险对于Greasemonkey / Tampermonkey脚本来说要小得多; Greasemonkey和Tampermonkey可以在他们的API中合理地提供这种功能(基本上包装扩展工作)。
考虑制作功能请求。



hacky解决方法:

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更新。请注意,如果只打开一个选项卡,则无法使用此功能。它只会关闭其他标签。


Firefox 可以抵御该攻击。因此,唯一的javascript方法是一次性删除一个浏览器的安全设置。

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

如果您的脚本仅供个人使用,请继续执行此操作。如果你要求其他人改变这种设置,那么他们就会变得聪明,并且有理由拒绝偏见。

Chrome目前没有等效设置。

答案 1 :(得分:29)

Chrome修复了版本36.0.1985.125

上的安全问题

Chrome 36.0.1985.125 2014年7月16日星期三 Release note

根据我的观察,此更新修复了使用window.close()关闭弹出窗口的问题。当它失败时,你会在控制台中看到这个,"脚本可能只关闭它打开的窗口。"。这意味着 hacky workarounds (Brock Adams的答案)可能无法在最新版本中使用

因此,在之前的Chrome发布的版本中,以下代码块可能有效,但不适用于此更新。

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

对于此更新,您必须相应地更新代码以关闭弹出窗口。其中一个解决方案是获取弹出窗口ID并使用

chrome.windows.remove(integer windowId, function callback)

删除它的方法。 Chrome扩展程序窗口API可在chrome.windows找到。

实际上我的Chrome扩展程序MarkView正面临这个问题,我不得不更新我的代码以使其适用于此Chrome更新。顺便说一下,MarkView是读取和编写Awesome Markdown文件的工具,它提供的功能包括内容大纲,可排序表和带行号的代码块语法高亮。

我也创建了this post,欢迎任何评论。

答案 2 :(得分:16)

现在在tampermonkey中你可以使用

// @grant        window.close

然后只需致电

window.close();

答案 3 :(得分:13)

我正在使用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& S测试版进行了测试。 10.10如果不同的话。


完整的代码:

HTML:

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

JavaScript的:

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

尝试此测试页:(现已在Chrome 40和Firefox 35中测试)

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

答案 4 :(得分:9)

许多人仍在尝试使用javascript关闭Chrome浏览器。 以下方法仅在您将Chrome用作APP启动器时使用 - 例如自助服务终端!

我测试了以下内容:

我正在使用以下扩展程序:Close Kiosk

我正在遵循使用说明,它似乎工作得很好(确保在进行测试时清除缓存)。我使用的javascript是(附加到点击事件):

window.location.href = '/closekiosk';

我希望能帮助某人,因为这是我找到的唯一可行的解​​决方案。

注意:扩展程序似乎在后台运行并添加了Chrome托盘图标。它选中了以下选项:“让Chrome在后台运行”(或类似文字)。你可能需要玩它,直到它适合你。我取消选中它,现在它工作得很好!

答案 5 :(得分:7)

尽管认为它“显然是假的”,但你所说的“似乎是一种信念”实际上是正确的。 window.close的Mozilla文档说

  

只允许对使用window.open方法由脚本打开的窗口调用此方法。如果脚本未打开窗口,则JavaScript控制台中将显示以下错误:脚本可能无法关闭脚本未打开的窗口

你说它“应该仍然这样做”,但我不认为你会找到任何支持它的参考,也许你错误地记得了什么?

答案 6 :(得分:5)

我发现了一种适合我的新方式

var win = window.open("about:blank", "_self");
win.close();

答案 7 :(得分:4)

以下代码对我有用 -

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

Chrome 43.0.2357.81

上进行测试

答案 8 :(得分:2)

这可能已经过时了,但让我们回答一下。

我使用 top.close()来关闭标签页。 window.close()或其他开放...关闭对我不起作用。

答案 9 :(得分:1)

如果无法关闭脚本未打开的窗口,则可以使用以下代码破坏页面:

 document.getElementsByTagName ('html') [0] .remove ();

答案 10 :(得分:0)

就我而言,该页面需要关闭,但可能已通过链接打开,因此window.close将失败。

我选择的解决方案是发出window.close,然后发出window.setTimeout,该重定向到另一个页面。

这样,如果window.close成功,则该页面上的执行将停止,但是如果失败,则将在一秒钟内将其重定向到另一个页面。

window.close();
window.setTimeout(function(){location.href = '/some-page.php';},1000);

答案 11 :(得分:0)

您也可以在下面尝试使用我的代码。这也将帮助您重定向父窗口:

父母:

dependencies

弹出窗口:

<script language="javascript">

function open_a_window() 
{
    var w = 200;
        var h = 200;
        var left = Number((screen.width/2)-(w/2));
        var tops = Number((screen.height/2)-(h/2));

        window.open("window_to_close.html", '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+tops+', left='+left);

   return false;
}

// opener:
window.onmessage = function (e) {
  if (e.data === 'location') {
    window.location.replace('https://www.google.com');
  }
};

</script>

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

答案 12 :(得分:0)

对于使用锚标记打开子窗口的用户,this article 描述了解决此问题的方法。

我的理解是,在新版本的 Chrome 中,对于目标为 rel 的锚标记,noopener 属性默认设置为 _blank。因此,通过将其设置为 opener,您可以恢复旧的行为。

请注意,这是为了避免 tab-napping 攻击而引入的。

答案 13 :(得分:-1)

只有使用window.open()打开一个新窗口时,新窗口才能使用我上面提到的代码关闭。这对我来说非常有用:)注意:切勿使用href在新选项卡中打开页面。 Window.close()不适用于“href”。请改用window.open()。

答案 14 :(得分:-1)

对于TamperMonkey:

@grant window.close 

参考:https://www.tampermonkey.net/documentation.php#_grant

相关问题