Monday, August 24th, 2009

Cross domain iframe communication without location polling

Category: Ajax

<p>Piers Lawson has come up with an interesting new technique for cross domain communication using an iframe and not having to poll the location for a #hashchange:

Most articles on using the URL Fragment technique advocate the target iFrame polling its Location to detect changes in the fragment… perhaps checking 5 times a second. Julien Lecomte describes a variant that creates throw away proxy iFrame’s. These can check their location within an onload event handler, extract the message, then make a call to the target iFrame, passing in the message. Once complete, the iFrame can be deleted. This means polling is no longer required. Also, when combined with caching, it should be fast and remove the risk of missing a message.

This post by Michael Mahemoff provides a good introduction to both techniques.

I came across these blog entries after I had come up with something similar, but with a slight twist… it may not be new but I didn’t find any other examples along these lines. I used a permanent proxy frame instead of throw away proxies. However, rather than polling the Location, I signalled a new “message” was ready to be processed by resizing the proxy iFrame. The JavaScript within the proxy iFrame registers a resize handler which when triggered reads the message. This approach is more immediate than both the polling and the dynamic iFrame techniques. I’m not 100% sure on whether threading within browser could allow messages to be lost in the case of several being sent close together, but I don’t believe so.

It is interesting to see how it all works:

The Parent Page hosts two iFrames. One contains the Content to be displayed, the second is a Proxy that is moved out of sight (both iFrames are served by the same domain);

The Parent Page sends messages to the Content iFrame by changing the URL Fragment of the Proxy iFrame and signalling that a new message is available (by toggling the size of the Proxy):

javascript
< view plain text >
  1. function SendMessageToFrame(message) {
  2.     var elem = document.getElementById('innerFrameProxy');
  3.     elem.contentWindow.location = 'http://www.pierslawson.plus.com/Examples/CrossDomain/InnerFrameProxy.html#' + message;
  4.     elem.width = elem.width > 50 ? 50 : 100;
  5. }

The Proxy registers a handler that is called as its size is changed. The handler inspects the URL Fragment and passes the message on to the Content iFrame (this is allowed as it is not a cross domain call). It is this call that fails with Opera… there does not appear to be a way for the Proxy iFrame to get a handle to the Content iFrame. Internet Explorer and Firefox can use parent.frames["hostFrame"] to find the Content iFrame.

Nice work Piers!

Related Content:

Posted by Dion Almaer at 4:30 am
11 Comments

++++-
4.3 rating from 52 votes

11 Comments »

Comments feed TrackBack URI

Such technique will never work in IE7. Some tomfool from MS IE team decided that changing location should make disturbing click sound. This repulsive behavior can’t be disabled, so for each message, a new iframe has to be created, which is the only way to suppress clicking sounds.

Comment by steida — August 24, 2009

I’ve got to be honest, whilst polling for a change isn’t the proudest moment, it works fine.. a year from now we can probably expect most browsers to have native events anyway.

Comment by meandmycode — August 24, 2009

I am actually working on using the resize technique in the easyXDM library, I had a working prototype of it earlier but it got lost.

Btw, any chance your gonna post about easyXDM anytime soon?

Comment by oyvindkinsey — August 24, 2009

does anyone knows how to upload files using crossdomain ? and handling the readystate or onload event

Comment by marlonbtx — August 24, 2009

The cross-domain channel library developed for Windows Live’s contacts web control back in 2006/2007 used a permanent iframe endpoint. Here’s an article about it:
http://msdn.microsoft.com/en-us/library/bb735305.aspx Derivatives of this library are now being used by other Microsoft web applications (alongside HTML5 message passing and other techniques when available – the iframe technique is the absolute last resort, but it does work everywhere).

IFrames are expensive in terms of memory and time to create and destroy. Probably not an issue for a one-off message you want to throw over the wall, but throw-away iframes become an issue in a high volume long life reliable data channel between A and B.

-Danny

Comment by dannythorpe — August 24, 2009

“IFrames are expensive in terms of memory and time to create and destroy. Probably not an issue for a one-off message you want to throw over the wall, but throw-away iframes become an issue in a high volume long life reliable data channel between A and B.”

Nevermind leaks!

Comment by eyelidlessness — August 24, 2009

Unfortunately this example seems not to work in IE6, an my own experiments with the resize event has also so far been unsuccessfull with IE6.
I have on the other hand had success using a #top fragment coupled with a onscroll event, working on integrating that into easyXDM (http://kinsey.no/blog/index.php/2009/08/20/easyxdm/) now.

Comment by oyvindkinsey — August 24, 2009

Never had problems with cross domain stuff using ExtJS… just use the inbuilt proxies…

Comment by dawesi — August 24, 2009

A while back there was a post about how to use postMessage for x domain iframe communication. A solution like this should check for postMessage support and not bother creating proxy frames. perhaps it could even provide backwards support for the html5 post message api.
I have put an example of 2 way communication with HTML5 postMessage on http://ryanday.org i hope it helps someone =).

Comment by soldair — August 25, 2009

this just what easyXDM is, a library that uses the best metod, postMessage or hash/fragment to communicate.

Comment by oyvindkinsey — August 25, 2009

Leave a comment

You must be logged in to post a comment.