窗口。亲近与自我。close不关闭Chrome中的窗口

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

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

更新:虽然很多建议都有严重的局限性和可用性问题,但最新的建议(具体到TamperMonkey)在脚本头中使用// @grant window.close,即使是在那些通常不能处理close方法的选项卡上,也经常会奏效。虽然不完全理想,也不适用于所有情况,但在我的情况下,这是一个很好的解决方案。

697996 次浏览

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

此方法只允许被脚本使用该窗口打开的窗口调用。开放的方法。如果该窗口不是由脚本打开的,则在JavaScript控制台中出现以下错误:脚本不能关闭未由脚本打开的窗口

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

普通javascript不能随意关闭窗口。这是一个安全特性,在一段时间前推出,以阻止各种恶意利用和烦恼。

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

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

  • 对应的浏览上下文一个script-closable
  • 当前脚本的浏览上下文熟悉浏览上下文一个
  • 当前脚本的浏览上下文被允许导航浏览上下文一个

如果一个浏览上下文是是由脚本创建的的辅助浏览上下文(而不是用户的操作),或者它是一个会话历史记录只包含一个Document的浏览上下文,则它是script-closable

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

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

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


如果你尝试从Greasemonkey / Tampermonkey / userscript中使用window.close,你将得到 Firefox:错误信息,"Scripts may not close windows that were not opened by script."
Chrome浏览器:只是无声失败。

< br >


长期解决方案:

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

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

< br >


俗气的变通方法:

目前容易受到“自重定向”漏洞的攻击。所以像这样的代码在一般情况下是有效的:

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

这是错误的行为,我认为,现在(大约在2015年4月)大部分被阻止。如果标签页是新打开的,并且在浏览历史中没有页面,它仍然可以从注射代码只< em > < / em >工作。所以它只在很小的情况下有用。

然而,一个变种仍然适用于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);

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

< p > < br > Firefox是安全的。所以,javascript唯一的方法就是削弱安全设置,一次一个浏览器。

你可以打开about:config并设置
allow_scripts_to_close_windowstrue。< / p >

如果您的脚本是供个人使用的,那么就这样做吧。如果你让其他人打开这个设置,他们会明智而合理地带着偏见拒绝。

目前Chrome没有相应的设置。

这工作的要求:

你必须从窗口启动器打开窗口/标签,以获得一个javascript句柄,以使其工作,因为它并不总是工作在一个标签,没有通过窗口启动器脚本打开。这个测试页面向您展示了如何:

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

如果你没有看到它工作在我的启动器,张贴你的浏览器,你的设备和版本是必要的。不同版本的浏览器在不同设备上的表现不同。(比如ipad上的火狐浏览器和Chrome浏览器,并不是他们所说的那样。他们是不同皮肤的Safari !)

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

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

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

我调用它从一个按钮按下,所以它是用户发起的,它仍然工作良好使用Chrome 90, Internet Explorer 11, Edge, Safari 7-10和Firefox 35 &88. 我使用8.1版本进行测试;10 Windows和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" />

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

Chrome 36.0.1985.125 2014年7月16日星期三 发行通知 < / p >

根据我的观察,这次更新修复了使用window.close()关闭弹出窗口的问题。当它失败时,你会在控制台中看到这一点,“脚本可能只关闭由它打开的窗口。”这意味着在最新版本中俗气的变通办法 (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文件,它提供的功能包括内容大纲,可排序表和代码块语法突出显示与行号。

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

许多人仍在尝试使用javascript关闭Chrome浏览器。以下方法只适用于当你使用Chrome作为应用程序启动器- kiosk为例!

我测试了以下内容:

我使用以下扩展:关闭亭

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

window.location.href = '/closekiosk';

我希望这能帮助到一些人,因为这是我找到的唯一有效的解决方案。

注意:似乎扩展运行在后台,并添加了一个Chrome托盘图标。它有以下选项选中:“让Chrome运行在后台”(或类似的文本)。你可能需要玩它,直到它为你工作。我检查它,现在它工作得很好!

这可能有点老了,但还是回答吧。

我使用top.close ()来关闭一个制表符。window.close ()或其他开放…亲密对我没用。

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

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

下面的代码对我有用

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

Chrome 43.0.2357.81上测试

只有当你使用window.open()打开一个新窗口时,新窗口才能像我上面提到的那样使用代码关闭。这对我来说是完美的:)注意:永远不要使用href在一个新选项卡中打开页面。Window.close()对"href"无效。请改用window.open()。

试试这样做onclick="return self.close()"

在tampermonkey中你可以使用

// @grant        window.close

然后简单地调用

window.close();

在我的例子中,页面需要关闭,但可能已经通过链接打开,因此window.close将失败。

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

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

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

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

家长:

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

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

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

所以它启动了,以kiosk模式启动Chrome,并且已经在正确的地址。这恰好很容易满足规范中的第二个选项:

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

因此,简单地从我的kiosk应用程序只是工作调用window.close() !

TamperMonkey:

@grant window.close

裁判:https://www.tampermonkey.net/documentation.php#_grant

如果你不能关闭脚本没有打开的窗口,那么你可以使用下面的代码销毁你的页面:

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

对于那些使用锚标记打开子窗口的程序,这篇文章描述了这个问题的解决方案。

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

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