提问人:GµårÐïåñ 提问时间:11/4/2013 最后编辑:GµårÐïåñ 更新时间:7/18/2023 访问量:733929
window.close 和 self.close 不会在 Chrome 中关闭窗口
window.close and self.close do not close the window in Chrome
问:
问题是当我调用或它没有关闭窗口时。现在似乎有一种信念,即在 Chrome 中,您不能通过脚本关闭任何未创建脚本的窗口。这显然是错误的,但无论如何,它仍然应该这样做,即使它需要弹出警报来确认。这些都没有发生。window.close()
self.close()
那么,有没有人有真实、实用且经过验证的方法来关闭窗口,使用类似的东西或实际上可以达到预期效果,并且在每个非基于 Chrome 的浏览器中都能很好地发生一些事情?任何建议将不胜感激,我正在寻找特定于 Javascript 的解决方案,没有 JQuery 或第三方实现。javascript:window.close()
javascript:self.close()
更新:虽然建议的大部分内容都存在严重的局限性和可用性问题,但最新的建议(特定于 TamperMonkey)在脚本标题中使用 // @grant window.close
通常可以解决问题,即使在那些通常无法处理 close 方法的选项卡上也是如此。虽然不完全理想,也不能推广到所有情况,但在我的情况下,这是一个很好的解决方案。
答:
尽管认为这是“明显错误的”,但你所说的“似乎是一种信念”实际上是正确的。window.close的Mozilla文档说
仅允许对使用 window.open 方法的脚本打开的窗口调用此方法。如果窗口未由脚本打开,则 JavaScript 控制台中会显示以下错误:脚本可能无法关闭未由脚本打开的窗口
你说它“应该仍然这样做”,但我认为你找不到任何支持这一点的参考资料,也许你记错了什么?
普通的 JavaScript 不能随意关闭窗口。这是不久前推出的一项安全功能,用于阻止各种恶意攻击和烦恼。
如果满足以下所有条件,则 Window 对象上的方法应关闭浏览上下文 A:
close()
- 相应的浏览上下文 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 或更高版本)。使用显式和纯 .例如:@grant
window.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:config
allow_scripts_to_close_windows
true
如果您的脚本供个人使用,请继续执行。如果你要求其他人打开这个设置,他们会很聪明,也有理由带着偏见拒绝。
目前没有针对 Chrome 的等效设置。
评论
dom.allow_scripts_to_close_windows;false
true
要做到这一点,需要:
您必须从窗口启动器打开窗口/选项卡才能获得 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" />
评论
<button onclick="open(location,'_self').close()" >Close Window</button>
<button>
<input type="button">
window.open('', '_self', ''); window.close();
open(location, '_self').close();
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 文件的工具,它提供的功能包括内容大纲、可排序表格和带有行号的代码块语法突出显示。
我也创建了这篇文章,欢迎任何评论。
评论
open(location, '_self').close();
open()
36.0.1985.125 m
open(location, '_self').close();
(warning on this"Scripts may close only the windows that were opened by it."). It looked like
chrome.windows.remove
许多人仍在尝试找到一种使用 javascript 关闭 Chrome 浏览器的方法。以下方法仅在您使用 Chrome 作为 APP 启动器时才有效 - 例如信息亭!
我已经测试了以下内容:
我正在使用以下扩展:关闭 Kiosk
我正在按照使用说明进行操作,它似乎工作正常(确保在进行测试时清除缓存)。我使用的javascript是(附加到点击事件):
window.location.href = '/closekiosk';
我希望这对某人有所帮助,因为这是我找到的唯一可行的解决方案。
注意:该扩展程序似乎在后台运行并添加了一个 Chrome 托盘图标。它选中了以下选项:“让 Chrome 在后台运行”(或类似文本)。您可能需要使用它,直到它为您工作。我取消了它,现在它工作得很好!
这可能很老,但让我们来回答一下。
我使用 top.close() 关闭选项卡。 window.close() 或其他打开的... 关闭对我不起作用。
评论
"Scripts may not close windows that were not opened by script."
我找到了一种适合我的新方法
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),以便他们可以访问终端以执行系统更新。
因此,它已启动,在自助服务终端模式下启动Chrome,地址已经正确。这恰好很容易满足规范中的第二个选项:
如果浏览上下文是由脚本(而不是由用户的操作)创建的辅助浏览上下文,或者是会话历史记录仅包含一个文档的顶级浏览上下文,则该浏览上下文是脚本可关闭的。
因此,只需从我的自助服务终端应用程序拨打电话即可!window.close()
评论
对于 TamperMonkey:
@grant window.close
编号: https://www.tampermonkey.net/documentation.php#_grant
评论
如果无法关闭脚本未打开的窗口,则可以使用以下代码销毁页面:
document.getElementsByTagName('html')[0].remove();
评论
对于使用锚标记打开子窗口的用户,本文介绍了此问题的解决方法。
我的理解是,在新版本的 Chrome 中,对于带有 target 的锚标记,该属性默认设置为。因此,通过将其设置为,您可以恢复旧行为。rel
noopener
_blank
opener
请注意,引入此功能是为了避免标签式小睡攻击。
评论
window.close()
在 Chrome 中对我有用。window.close
<a href="javascript:window.close">CLOSE</a>