How to do cross-domain async iFrame POST’s the easy/robust way

iFrames, Everyone loves them.

Haha! OK seriously now.

Every seasoned web developer has come up against the need to POST data asynchronously  to a different domain that does not accept cross-domain headers, and the usual solution is an iFrame to post into.

The code is usually something like this:

var myForm = crel('form', {'class':'braintreeForm', method : 'post', target:'myDodgyIframe'});
var myFrame = crel('iframe', {name:'myDodgyIframe'});

And then some code to make this disgusting pile of crap work:

var firstLoad;

myFrame.addEventListener('load', function(event){
    // the load event that gets fired on insertion
    if(!firstLoad){
        firstLoad = true;
        return;
    }

    var result;

    // the actual load event, probably.
    try{
        result = JSON.parse(event.target.contentDocument.documentElement.textContent);
    }catch(jsonError){
        //handle the error somehow
    }

    // use result if it parsed well.
});

An issue that you may encounter is that, if you are inserting the iFrame into the DOM arbitrarily, and not necessarily submitting it, the load event triggers every time it is inserted, not just once.

A solution to this came to me today:

myFrame.addEventListener('load', function(event){
    if(event.target.contentWindow.location.toString() === 'about:blank'){
        // ignorable load, return.
        return;
    }

    // useful load, use.
    var result;

    // the actual load event, probably.
    try{
        result = JSON.parse(event.target.contentDocument.documentElement.textContent);
    }catch(jsonError){
        //handle the error somehow
    }

    // use result if it parsed well.
    
    //cleanup
    event.target.contentWindow.location = 'about:blank';
});

This ignores any useless load events the frame might fire, without dodgy statefull ignore-the-first-load code.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s