Cross domain, cross window Javascript communication

The scenario: A typical meeting, they want to pop up our search screen, select an item and have it post back via Javascript the selected item. “Sure, no problem” I say. “Can you do cross domain Javascript like that” their dev asks, and I think for a second about all the IFrame proxy hacks I’ve seen and say “yeah, no problems”.

Doh.

So I get back to work, and talk to Ben-out-local-Javascript-god, who points me at the location-fragment for communication hack (see, for example Cross Domain Frame Communication with Fragment Identifiers (for Comet?)) and away I go.

I quickly discover that all the documentation on that is for use with frames, not windows, and windows work slightly different. For example, the parent window can’t poll the child for it’s location.hash, nor can the child set the parent’s location.hash.

Doh Doh.

Anyway to cut a long story short and to document it for anyone else, you can make it work. The child window needs to contain a iframe from the parent domain, then proxy communication though that. Modern non IE browsers can use Window.postMessage to do the same thing (Actually, IE8 supports Window.postMessage, too, but I couldn’t get it to work properly).

The core of the IE specific code looks like this. The child window uses this object:

/*
  XDCommsChild - Cross Domain Communication, Child Object.

   Create this in the child window with the address of the xdomaincomms.html file on the same domain as the parent window
*/
var XDCommsChild = function(xdomaincommsAddress) {
    this.xdomaincommsAddress = xdomaincommsAddress;

    this.isIe = isInternetExplorer();


    if (isIe) {
        // need hidden frame for communication. IE8 is supposed to support postMessage, but I can't get it to work properly
        document.writeln("")
    }

    this.postBack = function(data) {
        if (isIe) {
            // this method tested against IE6,7 & 8
            window.open(this.xdomaincommsAddress + '#data=' + data, 'xdcomms'); // MUST use window.open. frame.src or frame.location both fail
        } else {
            // for everything else - tested against Firefox 3, Chrome, Safari
            window.opener.postMessage(data, '*'); // should really restrict the domain data can come from here
        }
    }

    this.postBackAndCloseWindow = function(data){
        this.postBack(data);
        setTimeout("window.close()", 200); // need to use a timeout to make sure the javascript in the frame has executed if we are using that communication model
    }
}

Then the included proxy frame (deployed on the parent domain) looks like this:

          
           var hash = null;

            function sendData() {
                hash = location.hash;
                if (hash != null && hash.length > 1) {
                    window.parent.opener.location.hash=hash;
                    location.hash = '#';
                }
            }

            setInterval("sendData()", 50);

The the parent window uses this object:

/*
  XDCommsParent - Cross Domain Communication, Parent Object.

   Create this in the parent window with a callback function that will recieve data.
*/
var XDCommsParent = function(dataRecievedCallback) {
    this.dataRecievedCallback = dataRecievedCallback;
    
    this.isIe = isInternetExplorer();

    this.receiveMessage = function(event) {
        dataRecievedCallback(event.data);
    }

    if (this.isIe) {
        window.setInterval("pollForData()", 200);
    } else {
        window.addEventListener("message", this.receiveMessage, false);
    }

}

The final piece of the solution is calling it from the child window. I do this:

<button onclick="javascript:xDCommsChild.postBackAndCloseWindow(document.getElementById('thevalue').value);">Send to Parent Window</button>

4 thoughts on “Cross domain, cross window Javascript communication

  1. Hi Sorry to leave a random message on your blog like this, but I really couldn’t find a better way, and as a blogger myself i know i check this stuff all the time. You mentioned pubsubhub on twitter, and I was just looking for some help. I’d like to usepubsub hub on my aggregation website (tbablogs.com) but I’m not programmer and the people who i’ve hired to create the webpage don’t know too much about PSH (which worries me in the first place). So, I’m just looking to hire someone to hook this up for me, whether through creating my own hub or getting every member of my group to use feedburned. Any insight appreciated you have my email.
    thanks
    patrick

  2. Hi,
    Can you please let me know if this solution will work in case I need to postMesage/communicate from a popup (child, domain X) to his parent (domain Y)?

    I didn’t understand the solution with the hash…
    as far as I understand you suggest to include an invisible iFrame (with the parent’s domain address) in the popup (child) – and it seems to be a good idea – unfortunately I didn’t understand the rest of your solution…

    I succeed to solve it for all other browsers except for IE – frustrating!

    Any help will be highly appreciated,
    Thanks,

Leave a Reply

Your email address will not be published. Required fields are marked *