Javascript communicating cross-domain to parent wi

2019-01-23 21:59发布

问题:

I have written a tool for taking notes, grabbing images from web pages. It loads itself as a iFrame within the current window by using a javascript bookmark:

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); })();

I want to be able to close the tool by removing the iFrame from the parent window, when the user clicks on a close button.

What is the easiest way of doing this - Is it possible to close an iFrame within itself?

I've tried using cross-domain message posting. I have cross-domain posting working from the parent window to the child iFrame, but doesn't work from the iFrame to the parent window.

The code I have so far (which presumably contains the problem) is as follows.

In the parent window through the dynamically loaded 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();
}

In the iFrame, the button to close the iFrame calls:

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

The removeFrame call in the iFrame doesn't result in the removeFrame being called in the parent window.

So how should I actually remove the iFrame.

回答1:

postMessage is probably what you're looking for. Mozilla has documented this and it has fairly decent cross browser support:

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

I also wrote a library around this concept, it may need a little debugging but it is available on github: https://github.com/tsharp/OF.Core.js/blob/master/js/of/window.messaging.js

From here you'll need an event listener on the parent window to handle all incoming requests ... which will remove the iframe from the parent context. Here is an example of registering the message received event.

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