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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19761241/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 16:42:44  来源:igfitidea点击:

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

javascriptgoogle-chromegreasemonkeytampermonkey

提问by Gμ?rD???

The issue is that when I invoke window.close()or self.close()it doesn't close the window. Now there seems to be a belief that in Chrome you can't close by script any window that is not script created. That is patently false but regardless it is supposed to still do it, even if it requires to pop up an alert to confirm. These are not happening.

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

So does anyone have real, functional and proven method of closing a window using something like javascript:window.close()or javascript:self.close()that actually does what is expected and something that happens just fine in every browser that is NOT Chrome based? Any suggestions would be greatly appreciated and I am looking for Javascript specific solution, nothing JQuery or third party implementation.

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

Update:While much of what has been suggested has serious limitations and usability issues, the latest suggestion (specific to TamperMonkey) using // @grant window.closein the script header will often do the trick even on those tabs that normally can't handle the close method. While not entirely ideal and doesn't generalized to every case, it is a good solution in my case.

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

回答by Brock Adams

Ordinary javascript cannot close windows willy-nilly. This is a security feature, introduced a while ago, to stop various malicious exploits and annoyances.

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

From the latest working spec for window.close():

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

The close()method on Window objects should, if all the following conditions are met, close the browsing context A:

  • The corresponding browsing context Ais script-closable.
  • The browsing context of the incumbent script is familiar with the browsing context A.
  • The browsing context of the incumbent script is allowed to navigate the browsing context A.

A browsing context is script-closableif it is an auxiliary browsing context that was created by a script(as opposed to by an action of the user), or if it is a browsing context whose session history contains only one Document.

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

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

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

This means, with one small exception, javascript must not be allowed to close a window that was not opened by that same javascript.

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

Chrome allows that exception -- which it doesn't apply to userscripts -- however Firefox does not. The Firefox implementation flat out states:

Chrome 允许该异常——它不适用于用户脚本——但 Firefox 不允许。 Firefox 实现明确指出

This method is only allowed to be called for windows that were opened by a script using the window.openmethod.

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



If you try to use window.closefrom a Greasemonkey / Tampermonkey / userscript you will get:
Firefox:The error message, "Scripts may not close windows that were not opened by script."
Chrome:just silently fails.

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





The long-term solution:

长期解决方案:

The best way to deal with this is to make a Chrome extension and/or Firefox add-on instead.These can reliably close the current window.

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

However, since the security risks, posed by window.close, are much less for a Greasemonkey/Tampermonkey script; Greasemonkey and Tampermonkey could reasonably provide this functionality in their API (essentially packaging the extension work for you).
Consider making a feature request.

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





The hacky workarounds:

hacky的解决方法:

Chromeis currentlywas vulnerable to the "self redirection" exploit. So code like this used to work in general:

Chrome目前很容易受到“自我重定向”漏洞的攻击。所以像这样的代码过去通常可以工作:

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

This is buggy behavior, IMO, and is now (as of roughly April 2015) mostly blocked. It will still work from injectedcode onlyif the tab is freshly opened and has no pages in the browsing history. So it's only useful in a very small set of circumstances.

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

However, a variation still works on Chrome (v43 & v44) plus Tampermonkey (v3.11 or later). Use an explicit @grantand plain window.close(). EG:

但是,一个变体仍然适用于 Chrome (v43 & v44) 和 Tampermonkey (v3.11 或更高版本)。使用显式@grant和简单的window.close(). 例如:

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

setTimeout (window.close, 5000);

Thanks to zanetufor the update. Note that this will not work if there is only one tab open. It only closes additional tabs.

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


Firefoxis secure against that exploit. So, the only javascript way is to cripple the security settings, one browser at a time.


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

You can open up about:configand set
allow_scripts_to_close_windowsto true.

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

If your script is for personal use, go ahead and do that. If you ask anyone else to turn that setting on, they would be smart, and justified, to decline with prejudice.

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

There currently is no equivalent setting for Chrome.

目前没有适用于 Chrome 的等效设置。

回答by swcool

Chrome Fixed the security issues on version 36.0.1985.125

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

Chrome 36.0.1985.125 WEDNESDAY, JULY 16, 2014 Release note

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

From my observation, this update fixed the issue on using window.close()to close the popup window. You will see this in the console when it fail, "Scripts may close only the windows that were opened by it.". That means The hacky workarounds(Brock Adams's answer) may not workin the latest release.

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

So, in the previous Chrome released builds, the below code block may worked but not with this update.

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

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

For this update, you have to update your code accordingly to close the popup window. One of the solution is to grab the popup window id and use

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

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

method to remove it. Chrome extension windows API can be found at chrome.windows.

去除它的方法。Chrome 扩展窗口 API 可以在chrome.windows找到。

Actually my chrome extension MarkViewwas facing this issue and I had to update my code to make it work for this Chrome Update. By the way, MarkView is tool to read and write Awesome Markdown Files, it provides features including Content Outline, Sortable Tables and code block syntax highlight with line number.

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

I also created this post, any comments are welcome.

我也创建了这个帖子,欢迎任何评论。

回答by balping

In tampermonkey now you can use

在 tampermonkey 现在你可以使用

// @grant        window.close

And then just simply call

然后只需简单地调用

window.close();

回答by Jeff Clayton

I am using the method posted by Brock Adams and it even works in Firefox, if it's user initiated.

我正在使用 Brock Adams 发布的方法,如果它是用户启动的,它甚至可以在 Firefox 中使用。

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

I am calling it from a button press so it is user initiated, and it is still working fine using Chrome 35-40, Internet Explorer 11, Safari 7-8 and ALSO Firefox 29-35. I tested using version 8.1 of Windows and Mac OS X 10.6, 10.9 & 10.10 if that is different.

我是通过按下按钮调用它,因此它是用户启动的,并且在使用 Chrome 35-40、Internet Explorer 11、Safari 7-8 和 Firefox 29-35 时仍然可以正常工作。如果不同,我使用 8.1 版的 Windows 和 Mac OS X 10.6、10.9 和 10.10 进行了测试。



Self-Closing Window Code (on the page that closes itself)

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

The complete code to be used on the user-opened window that can close itself:

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

window_to_close.htm

window_to_close.htm

JavaScript:

JavaScript:

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

HTML:

HTML:

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

Try this test page: (Now tested in Chrome 40 and Firefox 35)

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

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

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



Window Opener Code (on a page that opens the above page)

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

To make this work, security-imposed cross browser compatibility requires that the window that is to be closed must have already been opened by the user clicking a button within the same site domain.

为了实现这一点,安全强加的跨浏览器兼容性要求要关闭的窗口必须已经被用户单击同一站点域中的按钮打开。

For example, the window that uses the method above to close itself, can be opened from a page using this code (code provided from my example page linked above):

例如,使用上述方法关闭自身的窗口,可以使用此代码从页面打开(代码来自我上面链接的示例页面):

window_close_tester.htm

window_close_tester.htm

JavaScript:

JavaScript:

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

    return false;
}

HTML:

HTML:

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

回答by Minister

Many people are still trying to find a way to close the Chrome browser using javascript. The following method only works when you use Chrome as APP launcher - kiosk for example!

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

I have tested the following:

我已经测试了以下内容:

I'm using the following extension: Close Kiosk

我正在使用以下扩展程序:关闭信息亭

I'm following the usage instructions and it seems to work just fine (make sure you clear the cache while doing the tests). The javascript I use is (attached to click event):

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

window.location.href = '/closekiosk';

I hope that helps somebody, as it's the only working solution I have found.

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

Note: It seems the extension runs in background and adds a Chrome tray icon. It has the following option checked: "Let Chrome run in background" (or similar text). You may need to play with it, until it work for you. I unchecked it and now it works just fine!

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

回答by Gareth

Despite thinking it is "patently false", what you say "seems to be a belief" is actually correct. The Mozilla documentation for window.closesays

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

This method is only allowed to be called for windows that were opened by a script using the window.open method. If the window was not opened by a script, the following error appears in the JavaScript Console: Scripts may not close windows that were not opened by script

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

You say that it is "supposed to still do it" but I don't think you'll find any reference which supports that, maybe you've misremembered something?

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

回答by Gerardo Abdo

I found a new way that works for me perfetly

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

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

回答by DfrDkn

The below code worked for me -

以下代码对我有用-

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

Tested on Chrome 43.0.2357.81

Chrome 43.0.2357.81上测试

回答by Soley

This might be old, but let's answer it.

这可能是旧的,但让我们回答它。

I use top.close()to close a tab. window.close()or other open...close didn't work for me.

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

回答by simon tan

For TamperMonkey:

对于 TamperMonkey:

@grant window.close 

Ref: https://www.tampermonkey.net/documentation.php#_grant

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