代码之家  ›  专栏  ›  技术社区  ›  Danack

Javascript跨域通信到iframe的父窗口

  •  1
  • Danack  · 技术社区  · 13 年前

    我已经写了一个工具来做笔记,从网页上抓取图像。它通过使用javascript书签将自己加载为当前窗口中的iFrame:

    javascript:(function(){   _my_script=document.createElement('SCRIPT');   _my_script.type='text/javascript';   _my_script.src='http://basereality.test/js/bookmarklet.js?rand='+(Math.random());   document.getElementsByTagName('head')[0].appendChild(_my_script); })();
    

    当用户单击关闭按钮时,我希望能够通过从父窗口中删除iFrame来关闭该工具。

    最简单的方法是什么?有可能关闭iFrame本身吗?

    我已经尝试过使用跨域消息发布。我有从父窗口到子iFrame的跨域发布,但不能从iFrame到父窗口。

    到目前为止,我所拥有的代码(可能包含这个问题)如下。

    在父窗口中,通过动态加载的Javascript:

    function    addiFrame(domain){
        var iframe_url = "http://" + domain + "/bookmarklet";
    
        var div = document.createElement("div");
        div.id = bookmarkletID;
    
        var str = "";
    
        iframe_url += "?description=" + encodeURIComponent(document.title);
        iframe_url += "&URL=" + encodeURIComponent(document.URL);
    
        str += "<div>";
        str += "<iframe frameborder='0' class='toolPanelPopup dragTarget' style='z-index: 1000'  name='bookmarklet_iframe' id='bookmarklet_iframe' src='" + iframe_url + "' width='550px' height='255px' style='textalign:right; backgroundColor: white;' />";
    
        str += "</div>";
    
        div.innerHTML = str;
    
        document.body.insertBefore(div, document.body.firstChild);
    }
    
    
    function jQueryLoadedCallback(){
    
        jQueryAlias = jQuery.noConflict();
        jQueryAlias('#' + bookmarkletID).bind('basereality.removeFrame', removeFrame);
    }
    
    function removeFrame(){
        alert("Calling remove frame");
        $("#" + bookmarkletID).remove();
    }
    

    在iFrame中,关闭iFrame的按钮调用:

    function removeFrame(){
        var params = {};
        params.message = 'basereality.removeFrame';
        parent.postMessage(params, "*");
    }
    

    iFrame中的removeFrame调用不会导致在父窗口中调用removeFrame。

    那么,我应该如何实际删除iFrame呢。

    1 回复  |  直到 13 年前
        1
  •  9
  •   Travis Sharp    10 年前

    postMessage可能就是你想要的。Mozilla已经记录了这一点,并提供了相当不错的跨浏览器支持:

    https://developer.mozilla.org/en-US/docs/DOM/window.postMessage

    我还围绕这个概念写了一个库,它可能需要一些调试,但它可以在github上使用: https://github.com/tsharp/OF.Core.js/blob/master/js/of/window.messaging.js

    从这里开始,您需要在父窗口上有一个事件侦听器来处理所有传入的请求。。。这将从父上下文中移除iframe。以下是注册消息接收事件的示例。

    function registerWindowHandler() {
        if (typeof window.addEventListener !== 'undefined') {
        window.addEventListener('message', receiveMessage, false);
        } else {
        // Support for ie8
        window.attachEvent('onmessage', receiveMessage);
        }
    }