我需要使用window.open('...', '_blank');
生成一个标签
然后,当用户单击按钮(按钮在新选项卡中)时,我需要该选项卡关闭它自己。
我控制了两个应用程序的代码库和服务器。
我试了如下:
在应用# 1:window.tab = window.open('http://localhost:5007', '_blank');
在应用# 2:function clickedButton() {
window.opener.tab.close();
}
不幸的是,我得到安全异常:错误:阻止了一个原点为http://localhost:5007的帧访问跨原点帧。
如何解决这个错误?有没有办法让我用这个库来克服这个问题?https://github.com/ternarylabs/porthole
我将在这里简单地引用文档,供任何需要参考的人单击W3C和MDN。
function openWin() {
myWindow = window.open("", "myWindow", "width=200, height=100"); // Opens a new window
}
function closeWin() {
myWindow.close(); // Closes the new window
}
为了打破它,open
和close
函数使用的参数可能非常有用,例如URL
,当希望打开或关闭当前窗口时,或者在您的情况下,打开的窗口。
我希望它有帮助!
编辑
要回答OP的编辑对这个问题的回答:如果它是在打开的窗口上触发事件的问题,您可以在新窗口上有一个事件处理程序,它将像这样触发window.close()
:
$('#anElementId').click(function() { window.opener.$('body').trigger('theCloseEvent', anyPassedData); })
然而,如果你真的有控制新的选项卡,因为它导致一个URL的代码库在你的控制,那么它只是一个触发事件的问题,你可以触发一旦窗口加载,或者一旦你点击一个按钮…像这样:
HTML<button id="close-window">Close me</button>
Javascript/jQuery: $(document).ready(function(){
$("#close-window").click(function(){
alert("ok");
window.close();
});
});
编辑# 2
为了进一步扩展OP的编辑,我想在这里包括一个在试图触发打开的窗口自行关闭时很容易遇到的问题。
引用自我如何关闭浏览器窗口而不收到"您要关闭此窗口"提示?:
脚本不允许关闭用户打开的窗口。这被认为是一种安全风险。虽然没有任何标准,但所有的浏览器供应商都遵循这个(Mozilla文档)。如果在某些浏览器中发生这种情况,这是一个安全漏洞,(理想情况下)会很快得到修补。
在这个问题的答案中没有一个hack可以再工作了,如果有人想出另一个肮脏的hack,最终它也会停止工作。
我建议你不要浪费精力与之抗争,而应该接受浏览器提供给你的有用方法——在你的页面似乎崩溃之前询问用户。
换句话说,除非你的网页的脚本有窗口打开的控制,你应该/不能关闭该窗口。这是因为运行window.close
的脚本不控制打开的窗口。
编辑# 3
我知道这么多编辑!但我是在我的日常工作中回答这个问题的,所以请原谅我。要回答porthole.js的问题,应该更有可能使用它做一些事情,但是您需要意识到您正在使用iframe。
在使用网站和使用iframes时有一个显著的区别,其中iframes是小部件,网站(包括迷你网站)有一个URL。在安全性和沙箱方面也有很多需要考虑的问题,正如在这里的portolejs演示中看到的那样。这种差异也不允许你以你最初想要的方式在不同的网站上工作。
我的建议是评估你的选择,关于你的实施:网站到网站vs网站到小部件。
祝你好运!
好了,我能够按照我使用porthole.js的理论方法完成这一点。我相信这是唯一的跨浏览器的方式来实现这一点,而不使用hack。
解决方案由2个应用程序组成(你必须在两个应用程序中添加代码才能使其工作)。
app #1: http://localhost:4000
app #2: http://localhost:5000
在我的例子中,我需要应用#1来生成包含应用#2的需求标签。然后我需要app#2能够在点击app#2中的按钮时自动关闭。
如果这些应用程序在相同的域(包括相同的端口),这将是相对容易通过保存一个引用标签在app#1:
window.tab = window.open('...', '_blank');
然后通过window.opener.tab.close()
从app#2中访问该引用
然而,对于我来说,应用程序需要在不同的域上,这样做会导致浏览器安全异常。所以,相反,我需要做的是主机应用程序#2内的iframe应用程序#1(在一些特定的路由,说/iframe),这样他们是在同一域就浏览器窗口而言,现在第二个选项卡应该能够使用window.opener.tab.close()
关闭自己。
然而,一个问题仍然存在,因为我需要触发器是一个按钮在app#2内(又名iframe内的按钮),并且由于托管应用程序和iframe应用程序再次不在同一域,似乎我会回到广场一…或者不是。
在这种情况下,porthole.js节省了时间。你必须将porthole.js加载到两个应用程序中(这就是为什么你需要访问两个代码库)。下面是代码:
in app#1 (http://localhost:4000/iframe)
// create a proxy window to send to and receive messages from the iFrame
var windowProxy;
window.onload = function() {
windowProxy = new Porthole.WindowProxy(
'http://localhost:5000', 'embedded-iframe');
windowProxy.addEventListener(function(event) {
//handle click event from iframe and close the tab
if(event == 'event:close-window') {
window.opener && window.opener.tab && window.opener.tab.close();
}
});
}
in app#2:(http://localhost:5000)
var windowProxy;
window.onload = function() {
windowProxy = new Porthole.WindowProxy(
'http://localhost:4000/#/iframe');
$('button').on('click', function() {
windowProxy.post('event:close-window');
});
}
和wah -lah,一个自动关闭标签。