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

window.close and self.close do not close the window in Chrome

提问人:GµårÐïåñ 提问时间:11/4/2013 最后编辑:GµårÐïåñ 更新时间:7/18/2023 访问量:733929

问:

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

那么,有没有人有真实、实用且经过验证的方法来关闭窗口,使用类似的东西或实际上可以达到预期效果,并且在每个非基于 Chrome 的浏览器中都能很好地发生一些事情?任何建议将不胜感激,我正在寻找特定于 Javascript 的解决方案,没有 JQuery 或第三方实现。javascript:window.close()javascript:self.close()

更新:虽然建议的大部分内容都存在严重的局限性和可用性问题,但最新的建议(特定于 TamperMonkey)在脚本标题中使用 // @grant window.close 通常可以解决问题,即使在那些通常无法处理 close 方法的选项卡上也是如此。虽然不完全理想,也不能推广到所有情况,但在我的情况下,这是一个很好的解决方案。

javascript google-chrome Greasemonkey 篡改猴子

评论

1赞 mash 11/4/2013
window.close()在 Chrome 中对我有用。
4赞 Blender 11/4/2013
@G μårÐïåñ:嗯,不,不是。它与语言无关。这是浏览器实现的功能。如果你能写一个最小的例子来说明它是如何没有按照应有的方式工作的,我认为这可能比说“它不起作用”更有帮助。window.close
3赞 GµårÐïåñ 11/5/2013
我给你举了两个例子。为你拼出来,<a href="javascript:window.close">CLOSE</a>
5赞 George 10/11/2014
守护者是不正确的 JavaScript。试试 window.close() 它就可以工作了。window.close 只是一个变量名称,不会调用该函数(至少当我在 chrome 37 中测试它时它不会)。当我将您的示例更改为 window.close() 时,它可以在 chrome 37 中工作。
6赞 Superole 2/6/2015
GμårÐïåñ @George说的话没有实际意义(除非我完全误解了这个词的意思)。他正确地指出,您在示例中的javascript中存在语法错误,并且如果您的应用程序代码中存在相同的错误,那么这很可能是您问题的原因。但是,如果这些只是您示例中的错别字,那么您应该纠正这些错别字以获得更好的答案。

答:

15赞 Gareth 11/4/2013 #1

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

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

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

222赞 Brock Adams 11/4/2013 #2

普通的 JavaScript 不能随意关闭窗口。这是不久前推出的一项安全功能,用于阻止各种恶意攻击和烦恼。

window.close()的最新工作规范中:

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

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

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

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

Chrome 允许这种例外 - 它不适用于用户脚本 - 但 Firefox 不允许。 Firefox 实现直截了当地说

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


如果您尝试从 Greasemonkey / Tampermonkey / userscript 使用,您将获得:window.close()

  • 火狐浏览器:错误消息”Scripts may not close windows that were not opened by script."
  • Chrome:只是默默地失败。


长期解决方案:

解决这个问题的最好方法是制作一个Chrome扩展程序和/或Firefox插件。这些可以可靠地关闭当前窗口。

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



hacky解决方法:

Chrome 目前容易受到“自我重定向”攻击。所以像这样的代码过去一般都是有效的:

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

这是错误的行为,IMO,现在(大约截至 2015 年 4 月)大部分被阻止。当选项卡是新打开的并且浏览历史记录中没有页面时,它才能从注入的代码中工作。因此,它仅在极少数情况下有用。

但是,变体仍然适用于 Chrome(v43 和 v44)以及 Tampermonkey(v3.11 或更高版本)。使用显式和纯 .例如:@grantwindow.close()

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

setTimeout(window.close, 5000);

感谢 zanetu 的更新。请注意,如果只打开一个选项卡,这将不起作用。它只会关闭其他选项卡。


Firefox 可以抵御这种漏洞。因此,唯一的 JavaScript 方法是削弱安全设置,一次一个浏览器。

您可以打开并设置为
about:configallow_scripts_to_close_windowstrue

如果您的脚本供个人使用,请继续执行。如果你要求其他人打开这个设置,他们会很聪明,也有理由带着偏见拒绝。

目前没有针对 Chrome 的等效设置。

评论

4赞 GµårÐïåñ 11/5/2013
嘿,我的朋友,很高兴终于收到你的来信。请注意,在 Fx 上,您可以通过翻转到 来绕过该限制,但我想 Chrome 中什么都没有,除非破解源代码/重建,这就是我现在绕过它的方式。我知道并已经与 TM 开发人员交谈过,在最近的 alpha/beta 中,我们将其作为兼容性选项(脚本设置)以中间人风格运行,有效。我想除了黑客之外,我们没有干净的解决方案,可惜。dom.allow_scripts_to_close_windows;falsetrue
4赞 Bron Davies 2/26/2014
如果有人在使用 window.close 或浏览器之间的特定行为差异时遇到问题,请仔细阅读此答案 - 它确实拥有所有正确的信息。
1赞 Jscti 6/24/2014
有没有办法检查窗口是否被脚本打开?(我需要显示/隐藏后退按钮,我不想使用黑客)谢谢编辑:window.opener === null
0赞 swcool 7/21/2014
自 Chrome 36.0.1985.125 2014 年 7 月 16 日星期三以来,hacky 解决方法可能不起作用,详见我的回答。
4赞 zanetu 8/28/2015
window.close()如果您设置为 以外的值,则在 Tampermonkey 中将起作用。请参阅此线程@grantnone
23赞 Jeff Clayton 5/15/2014 #3

要做到这一点,需要:

您必须从窗口启动器打开窗口/选项卡才能获得 javascript 句柄才能使其工作,因为它并不总是在未通过窗口启动器脚本打开的选项卡上工作。此测试页演示如何:

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

如果您在我的启动器中看不到它的工作,则需要发布您的浏览器,您的设备和版本。不同版本的浏览器在不同的设备上有不同的行为。(例如iPad上的Firefox和Chrome,它们不是他们所说的那样。他们是具有不同皮肤的 Safari!

因此,例如,说“我在使用 iOs 14.5 的 iPad 上使用 Safari 10.14”很重要,这样我(或 stackoverflow 上的其他一些有用的人)就可以为您研究它并发布结果以帮助其他用户。提前感谢您这样做。如果您使用启动器并且它适用于我的示例,那么它就可以工作。

我正在使用 Brock Adams 发布的方法,它甚至可以在 Firefox 中工作,如果它是用户通过从另一个窗口启动的按钮或链接启动的。

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

我通过按下按钮来调用它,因此它是用户启动的,并且它仍然可以使用 Chrome 90、Internet Explorer 11、Edge、Safari 7-10 以及 Firefox 35 和 88 正常工作。我使用Windows的8.1和10版本以及Mac OS X 10.6,10.9和10.10以及10.14版本进行了测试。


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

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

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 90.0 和 Firefox 88.0 中进行了测试——在 Windows 10 和 Mac 10.14 Mojave 上)

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" />

评论

0赞 Brock Adams 5/16/2014
忘记了用户发起的异常;好渔获。不过,我认为大多数用户脚本编写者都希望全自动操作。他们已经有一个方便的、用户启动的关闭机制——右上角的那个小 X。(^_^)
3赞 LordOfThePigs 8/29/2014
不知何故,这对我不起作用。无论是在 firefox 30 上还是在 Chrome 37 上。它所做的只是使页面变为空白(非常奇怪的行为)。我的代码是.我是不是做错了什么?在我看来,这也是用户发起的。请注意,如果我使用 a 或 .<button onclick="open(location,'_self').close()" >Close Window</button><button><input type="button">
0赞 Jeff Clayton 8/29/2014
在上面的答案中为您添加了一个测试页面。
0赞 Jeff Clayton 4/16/2017
@YumYumYum感谢您的帖子,bitbucket.org 最近将链接更改为 bitbucket.io - 现在已在答案中修复
0赞 krystonen 7/3/2019
它对我有用(页面上有一个按钮可以关闭窗口)。不起作用的是:但它有效window.open('', '_self', ''); window.close();open(location, '_self').close();
35赞 swcool 7/21/2014 #4

Chrome 修复了版本 36.0.1985.125 上的安全问题

Chrome 36.0.1985.125 2014年7月16日星期三 发行说明

根据我的观察,此更新修复了用于关闭弹出窗口的问题。当它失败时,您将在控制台中看到此消息,“脚本可能仅关闭它打开的窗口。这意味着 hacky 变通方法(Brock Adams 的回答)在最新版本中可能不起作用window.close()

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

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

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

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

方法删除它。Chrome 扩展程序 Windows API 可在 chrome.windows 上找到。

实际上,我的 chrome 扩展程序 MarkView 遇到了这个问题,我不得不更新我的代码以使其适用于此 Chrome 更新。顺便说一句,MarkView 是读取和写入 Awesome Markdown 文件的工具,它提供的功能包括内容大纲、可排序表格和带有行号的代码块语法突出显示。

我也创建了这篇文章,欢迎任何评论。

评论

2赞 Brock Adams 7/21/2014
正确的 hack 是 -- 注意使用 的返回值 。这仍然适用于 Chromeopen(location, '_self').close();open()36.0.1985.125 m
0赞 swcool 7/21/2014
就我而言,我只是再次测试,我对此产生了“未经授权”错误。这个错误与'window.close()open(location, '_self').close();'不同,但在我的情况下无法完成。感谢 @brock-adams 的评论。open(location, '_self').close();(warning on this"Scripts may close only the windows that were opened by it."). It looked like
0赞 DevT 7/22/2014
我有打字稿,当我放它时说找不到符号铬。我该如何解决这个问题?我需要添加某种引用吗?chrome.windows.remove
0赞 swcool 7/23/2014
@devt chrome.windows.remove 是 Chrome 扩展程序 API,则 chrome 扩展程序应识别您的 javascript。您可以在 background.js 中尝试它,在您的 chrome 扩展程序中manifest.json您需要拥有: “background”: { “scripts”: [“background.js”], ... },
0赞 swcool 12/3/2016
我删除了MarkView登录功能,供用户自由访问。所以我上面提到的例子现在不可用。
15赞 Minister 8/6/2014 #5

许多人仍在尝试找到一种使用 javascript 关闭 Chrome 浏览器的方法。以下方法仅在您使用 Chrome 作为 APP 启动器时才有效 - 例如信息亭!

我已经测试了以下内容:

我正在使用以下扩展:关闭 Kiosk

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

window.location.href = '/closekiosk';

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

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

2赞 Soley 8/10/2014 #6

这可能很老,但让我们来回答一下。

我使用 top.close() 关闭选项卡。 window.close() 或其他打开的... 关闭对我不起作用。

评论

14赞 kad81 9/15/2014
这也受到其他答案中提到的问题的影响。"Scripts may not close windows that were not opened by script."
1赞 Bimal Das 8/4/2017
请给出您的答案的解决方案。请不要只讨论你的答案。
13赞 Gerardo Abdo 12/4/2014 #7

我找到了一种适合我的新方法

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

评论

1赞 Rotimi 3/8/2017
这是 2017 年,我仍然收到“脚本可能无法关闭未被脚本打开的窗口”的错误。
0赞 Gopal00005 8/9/2017
IE 11 确认按钮的好技巧。
0赞 Vineeth Pradhan 6/20/2018
适用于 Chrome 和 Firefox
5赞 Scott Christensen 4/30/2020
这个洞看起来已经被填满了。我不知道什么时候,但我使用的是最新的开发版本 84.x。加载空白页,但关闭不触发。
1赞 JOSAN THOMAS 12/27/2021
这对我不起作用。如果窗口自行打开,则不会关闭
10赞 DfrDkn 5/28/2015 #8

下面的代码对我有用 -

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

Chrome 43.0.2357.81 上测试

评论

12赞 alianos- 6/1/2015
对我来说,它只是用 /location 上的窗口替换当前窗口。
2赞 Subhajit 10/5/2017
在最新的 chrome 中不起作用 - 版本 61.0.3163.100(官方版本)(64 位)
0赞 Npythondev 7/9/2022
这对我有用,但我想保持在同一页面上,我应该如何处理<位置>的事情,我有相同的消息.html对于每个页面,我想关闭 Django 消息并保持在同一页面上,您的解决方案成功关闭了选项卡,但不允许我保持在同一页面上
-2赞 DfrDkn 5/28/2015 #9

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

评论

1赞 napstercake 8/9/2015
它只是替换了当前窗口。没有了。
-7赞 Ragven 8/27/2015 #10

试试这样的 onclick=“return self.close()”

24赞 balping 1/19/2016 #11

现在在 tampermonkey 中,您可以使用

// @grant        window.close

然后只需简单地打电话

window.close();

评论

0赞 GµårÐïåñ 2/17/2016
我已经确认这在许多情况下都有效,但仍然偶尔会固执,但总比没有好,谢谢。我会把它添加到帖子中。
2赞 mt025 4/3/2017
请注意:在 Greasemonkey 3.10 中不适合我
0赞 user889030 7/29/2020
你能添加适当的说明如何做吗,我是 Tampermonkey 的新手
3赞 user2182349 10/8/2018 #12

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

我选择的解决方案是发出 ,然后重定向到其他页面。window.closewindow.setTimeout

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

window.close();
window.setTimeout(function(){location.href = '/some-page.php';},1000);
-2赞 Lonare 12/5/2019 #13

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

父母:

<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" />

弹出:

<!DOCTYPE html>
<html>
<body onload="quitBox('quit');">

<h1>The window closer:</h1>

<input type="button" onclick="return quitBox('quit');" value="Close This Window/Tab" /> 


<script language="javascript">

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

</script>

</body>
</html>
2赞 Jonathan Tuzman 2/14/2020 #14

我想分享我对这个问题的“解决方案”。似乎我们大多数人都试图在标准浏览器会话中关闭浏览器窗口,用户在访问其他网站之后,在他们访问更多网站之前访问某个网站或另一个网站。

但是,我的情况是,我正在为设备构建一个 Web 应用程序,这基本上是设备唯一做的事情。您启动它,它会启动 Chrome 并导航到我们的应用程序。它甚至没有连接到互联网,它与之通信的任何服务器都在我们本地的 Docker 容器上。用户需要一种方法来关闭应用程序(又名关闭 Chrome),以便他们可以访问终端以执行系统更新。

因此,它已启动,在自助服务终端模式下启动Chrome,地址已经正确。这恰好很容易满足规范中的第二个选项:

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

因此,只需从我的自助服务终端应用程序拨打电话即可window.close()

评论

0赞 Envek 11/17/2020
感谢您分享有关展台模式的一点知识。我可以确认这一点,它有效!而这正是我真正想要的。
-4赞 simon tan 4/6/2020 #15

对于 TamperMonkey:

@grant window.close 

编号: https://www.tampermonkey.net/documentation.php#_grant

评论

0赞 Anton Menshov 4/6/2020
虽然这在理论上可以回答这个问题,但最好在这里包括答案的基本部分,并提供链接以供参考。
2赞 Ibnul Husainan 9/5/2020 #16

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

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

评论

1赞 GµårÐïåñ 9/6/2020
有趣的方法,我会在能看到的时候给一个测试。
0赞 Ibnul Husainan 9/7/2020
别忘了“销毁”你的脚本
0赞 Ayush Srivastava 10/26/2020
如何销毁脚本?
6赞 Larry Martell 4/29/2021
所有这一切都是清除窗口,但不会关闭选项卡。
2赞 Rahul 8/19/2021
在阅读了上面的所有答案之后,似乎也没有任何效果,包括这个答案。
1赞 Jacqueline Rodriguez 6/25/2021 #17

对于使用锚标记打开子窗口的用户,本文介绍了此问题的解决方法。

我的理解是,在新版本的 Chrome 中,对于带有 target 的锚标记,该属性默认设置为。因此,通过将其设置为,您可以恢复旧行为。relnoopener_blankopener

请注意,引入此功能是为了避免标签式小睡攻击。

评论

1赞 Dan Atkinson 9/12/2022
我的浏览器无法打开 5.9.10.113/67416662/...,因为它重定向到似乎具有无效 SSL/TLS 证书的 quabr.com。