简体   繁体   English

porthole.js-如何关闭使用window.open()从新标签页打开的标签页

[英]porthole.js - how can I close a tab that I opened using window.open(), but from the new tab

I need to spawn a tab using window.open('...', '_blank'); 我需要使用window.open('...', '_blank');生成选项卡

Then, I need that tab to CLOSE ITSELF, when the user click a button (button is in the new tab). 然后,当用户单击按钮(按钮在新选项卡中)时,我需要该选项卡关闭自己。

I have control over the codebase and server of both applications. 我可以控制两个应用程序的代码库和服务器。

I tried the following: 我尝试了以下方法:

in app#1: 在应用程式1中:

window.tab = window.open('http://localhost:5007', '_blank');

in app#2: 在应用程序2中:

function clickedButton() {
    window.opener.tab.close();
}

Unfortunately I get security exception: Error: Blocked a frame with origin " http://localhost:5007 " from accessing a cross-origin frame. 不幸的是,我遇到了安全异常:错误:阻止了源为“ http:// localhost:5007 ”的框架访问跨域框架。

How can I get around this error? 如何解决这个错误? Is there anyway I can use this library to overcome this? 无论如何,我可以使用这个库来克服这个问题吗? https://github.com/ternarylabs/porthole https://github.com/ternarylabs/porthole

I am simply going to quote documentation here, just for anyone who needs a reference click W3C and MDN . 我只是在这里引用文档,仅对需要参考的人单击W3CMDN

function openWin() {
    myWindow = window.open("", "myWindow", "width=200, height=100");   // Opens a new window
}

function closeWin() {
    myWindow.close();   // Closes the new window
}

To break it down, the open and close functions use parameters than can be very useful, such as the URL , when desiring to open or close the current window, or in your case the opened window. 要对其进行分解, openclose函数使用一些非常有用的参数,例如URL ,当您希望打开或关闭当前窗口时,或者在您希望打开的窗口中。

A practical example would be this stack overflow question. 一个实际的例子就是这个堆栈溢出问题。 N ñ

I hope it helps! 希望对您有所帮助!

EDIT 编辑

To answer the OP's edit to the question: If it is a matter of triggering an event on a window which was opened, you can on the new window have an event handler which will trigger window.close() like so: 要回答OP对问题的编辑 :如果是在打开的窗口上触发事件的问题,则可以在新窗口上有一个事件处理程序,它将触发window.close()如下所示:

$('#anElementId').click(function() { window.opener.$('body').trigger('theCloseEvent', anyPassedData); })

However, if you truly do have control over the new tab, because it leads to a URL whose code base you are in control of, then it is only a matter of triggering an event there that you can trigger either once the window loads, or once you click a button... like so: 但是,如果您确实可以控制新选项卡,因为它会导致您控制其代码库的URL,那么只需触发一个事件即可,您可以在窗口加载后或一旦您单击按钮...就像这样:

HTML 的HTML

<button id="close-window">Close me</button>

Javascript/jQuery: Javascript / jQuery:

$(document).ready(function(){
    $("#close-window").click(function(){
        alert("ok");
        window.close();
    });
});

EDIT #2 编辑#2

To further extend the OP's edit, I want to include here an issue that can easily be encountered when attempting to trigger the opened window to close itself. 为了进一步扩展OP的编辑,我想在此处包括一个问题,在尝试触发打开的窗口以自行关闭时很容易遇到。

Quoted from How can I close a browser window without receiving the “Do you want to close this window” prompt? 引自“ 如何关闭浏览器窗口而不收到“您要关闭此窗口”提示? :

Scripts are not allowed to close a window that a user opened. 不允许脚本关闭用户打开的窗口。 This is considered a security risk. 这被认为是安全风险。 Though it isn't in any standard, all browser vendors follow this (Mozilla docs). 尽管没有任何标准,但是所有浏览器供应商都遵循此标准(Mozilla文档)。 If this happens in some browsers, it's a security bug that (ideally) gets patched very quickly. 如果这在某些浏览器中发生,则是(非常理想的)快速修复补丁程序的安全漏洞。

None of the hacks in the answers on this question work any longer, and if someone would come up with another dirty hack, eventually it will stop working as well. 该问题答案中的所有hacks均无法正常工作,并且如果有人提出另一个肮脏的hacks,最终它将也停止工作。

I suggest you don't waste energy fighting this and embrace the method that the browser so helpfully gives you — ask the user before you seemingly crash their page. 我建议您不要为此浪费精力,而应采用浏览器如此有帮助的方法-在您看上去使他们的页面崩溃之前先询问用户。

In other words, unless your webpage's script has control of the window which was opened, you should/cannot close said window. 换句话说,除非您的网页脚本可以控制已打开的窗口,否则您应该/不能关闭该窗口。 That is because the script running the window.close is not in control of the opened window. 那是因为运行window.close的脚本不受打开的窗口的控制。

EDIT #3 编辑#3

So many edits I know! 我知道这么多编辑! But I am answering this in between my daily routine so bear with me. 但是我在日常工作中回答这个问题,所以请多多包涵。 To answer the porthole.js question, it should be much more possible to do something with it, however you need to realize that you are working with iframes. 要回答porthole.js问题,应该可以做更多的事情,但是您需要意识到自己正在使用iframe。

There is a significant difference when working with websites vs working with iframes , in which iframes are Widgets and websites (including mini sites) are given a URL. 使用网站与使用iframe相比有很大的不同,其中iframe是窗口小部件,并且为网站(包括小型网站)提供了URL。 There are lots of considerations as well in terms of security and sandboxing, as can be seen on the portholejs demo here . 在安全性和沙箱方面也有很多注意事项,如此处的portholejs演示所示 This difference is also what does not allow you to work with different websites the way you want to initially. 这种差异也是不允许您以最初的方式使用其他网站的原因。

My advise would be to evaluate your options with respect to your implementation: website to website vs website to widget. 我的建议是评估与您的实施相关的选项:网站到网站vs网站到小部件。

Good luck! 祝好运!

Ok, I was able to accomplish this in the way I theorized by using porthole.js. 好的,我能够通过使用porthole.js进行理论化的方式来完成此任务。 I believe this is the only cross-browser way to accomplish this without using hacks. 我相信,这是不使用黑客即可完成此操作的唯一跨浏览器方法。

The solution consists of 2 apps (you must add code to both app for this to work). 该解决方案包含2个应用程序(您必须将代码添加到两个应用程序中才能起作用)。

app #1: http://localhost:4000
app #2: http://localhost:5000

In my case, I needed app#1 to spawn a need tab containing app#2. 就我而言,我需要app#1生成一个包含app#2的需求标签。 Then I needed app#2 to be able to CLOSE ITSELF upon clicking a button inside app#2. 然后,我需要app#2才能通过单击app#2中的按钮来关闭它。

If these apps were on the same domain (including same port), this would be relatively easy by saving a reference to the tab in app#1: 如果这些应用程序位于相同的域(包括相同的端口)上,则通过将对应用程序1中的选项卡的引用保存到相对容易的方式:

window.tab = window.open('...', '_blank');

And then accessing that reference from within app#2 via window.opener.tab.close() 然后通过window.opener.tab.close()从应用程序2中访问该引用

However, for my case the apps needed to be on diff domains and doing this method resulted in a browser security exception. 但是,就我而言,这些应用程序必须位于差异域上,并且执行此方法会导致浏览器安全性异常。 So instead, what I needed to do was host app#2 within an iframe inside app#1 (on some specific route, say /iframe), this way they ARE on the same domain as far as the browser windows are concerned, and now the second tab should be able to close itself using window.opener.tab.close() . 因此,相反,我需要做的是将app#2托管在app#1内的iframe中(在某些特定路由上,例如/ iframe),这样就浏览器窗口而言,它们位于同一域上,现在第二个选项卡应该能够使用window.opener.tab.close()关闭自身。

However, a problem still remained because I needed the trigger to be a button INSIDE app#2 (aka a button inside the iframe), and since the hosting app and the iframe app are again not on the same domain, it seems like I would be back to square one... or maybe not. 但是,问题仍然存在,因为我需要将触发器设置为INSIDE app#2按钮(也就是iframe中的按钮),并且由于托管应用程序和iframe应用程序又不在同一域中,因此好像回到正题...也许不是。

In this case, porthole.js saves the day. 在这种情况下,porthole.js可以节省一天。 You must load porthole.js into both apps (this is why you need access to both codebases). 您必须将porthole.js加载到两个应用程序中(这就是为什么您需要访问两个代码库的原因)。 Here's the code: 这是代码:

in app#1 ( http://localhost:4000/iframe ) 在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 ) 在应用程序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');
        });
    }

And wa-lah, a self closing tab. 哇,一个自动关闭的标签。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在用 window.open 打开的新选项卡中创建提示 - How to create a prompt in a new tab opened with window.open 使用 window.open() 打开一个带有链接的新标签,我希望该标签在 15 秒后自动关闭 - opening a new tab with a link using window.open() and i want that tab close automatically after 15sec 在 Edge 浏览器中,如何执行 window.open() 而不是在新窗口或选项卡中保持会话? - In Edge browser, how can I do window.open() and not keeping session in the new window or tab? 与_blank的常规链接在选项卡中打开,但是JS window.open(url,“_ blank”); 打开一个新窗口? - A regular link with _blank gets opened in tab but a JS window.open(url, “_blank”); open a new window? 在浏览器窗口中打开新标签页(通过window.open打开) - Open new tab in browser window (opened with window.open) 在chrome中的新选项卡中查找以前由window.open打开的窗口 - Find window previously opened by window.open in new tab in chrome Window.open()无法正常工作+如何关闭标签页 - Window.open() not working + how to close a tab 如何从“ window.getSelection”获取字符串以及如何使用“ window.open”修复打开新标签页的问题? - How to get string from 'window.getSelection' and how to fix opening new tab by using 'window.open'? 新窗口或标签现在打开,我该如何检查 - new window or tab is opened now, How can i check it 使用 window.open() function 打开已打开的选项卡而不重新加载已打开的选项卡 - To open the already opened tab using window.open() function without reloading the already opened tab
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM