The iframe cross-domain policy problem

For Developers
Dec 21
/
5 min read
If you are a front-end developer that need to use a cross-domain iframe, you know pain. You could write a nice bit of code and get it working on firefox but it would crash on IE. You would think that would be easy – facebook, twitter and all the others cool kids are doing it! Well, not quite.
Screen with code

[This blogpost has been post in January 2011 and still is very much consulted - it's why we keep it online]

Here at Cakemail we are currently building a platform that will enable our users to create forms and embed them in their website directly (think an email list subscription form). So basically, we needed to have javascript control in the parent and in the child.

We had 2 problems to solve based on embedding. One was to change the iframe height dynamically (no way in hell were we going to save the iframe height in a database). And sometimes, depending on what functionality our users embedded in their website, we needed to actually redirect the parent page.

Visit Cakemail Next-gen for Developers
Visit Cakemail Next-Gen for developers

Why it is so hard?

Security: I’m sure I don’t really have to tell you what an intruder could do to your website if it had access to your document. It could bind itself to your login process and just get all your users email/password, redirect your website, etc. This is why implementing a cross-domain communication is not to be taken lightly.

Even if you do it right, you have to think about what could happen if your embedded script was compromised. Especially if you embed that script in other websites that are not yours!

Accessing to a parent window and document

Accessing to a parent document is really simple when you are on the same domain, you do a quick window.opener.MyParentFunction(), and you’re done.

However doing this cross-domain? Not so easy. You’ll get something along the line of: Child document does not have the right to access parent document. In fact there is a lot of documentation on the web about how to achieve it, but the problem is that it is often outdated, with solutions that often only works in a couples of browsers.

Doing it the old way: An iframe in an iframe in an iframe

A clever idea that popped up some time ago – embedding an iframe in your child window that’s on the same domain that your parent window. It works, most of the time, but there are variants to this technique where some work and some don’t. Some variants involve the url using a hash to pass data (#), which is really bad if you want to pass lots of data, and also makes annoying noise in IE and a horrible browsing history.

But remember that this is still a hack. You’re bypassing the protection using a somewhat clever idea, and there is always a chance that it will stop working one day with a browser update.

A nice resource for the old hacks

This website really gets into detail on how to make the iframe hacks work. It’s really useful if you want to understand in details how the iframe cross-domain policy works.

The HTML5 way

Ahhh HTML5, the savior of all our problems – right? For the cross-domain issue, HTML5 implemented a nice new javascript method, postmessage.

window.postmessage was specifically implemented to resolve the cross domain policy problem, safely (well as safe as possible..). Here’s what a communication would look like:

It comes with 2 options to make it as secure as possible, origin and source. Origin being the message domain origin and source being a reference to the window object.

What about ie?

Postmessage is in ie8, however it’s not in ie7 & ie6 (obviously). If you need to support those browsers you will have to rely on another technique.

You can get a really complete description and examples of postmessage on the Mozilla javascript documentation website.

As usual, for a good cross-browser solution we need to compromise

As with a lot of things with the DOM, the best way to do it cross browser is to use the best solution possible, and rely on hacks for older browsers.

Fortunately, that is exactly what easyXDM did for you. This library is (or has been) used by a lot of websites, including Twitter and Disqus! It gives you a nice api that works everywhere. Let’s have a look:

What about IE, how does easyXDM work its magic?

You would think that easyXDM use the simple iframes trick to work in ie7 & ie6, but in fact it use a much more clever hack. It use an ie only protocol (some kind of vbscript) that makes cross-domain communication possible, the NixTransport.

“This implementation therefore wraps the JavaScript objects used inside a VBScript class. Since VBScript objects are passed in JavaScript as a COM wrapper (like DOM objects), they are thus opaque to JavaScript (except for the interface they expose). This therefore provides a safe method of transport. Initially based on FrameElementTransport which shares some similarities to this method. “

Limitations

One clear limitation I noticed using this library is that loading a children window without being embedded from the parent make easyXDM throw a js error. There are ways on the forum to correct this using a third window but it’s not really convenient, I also did some tests with the onReady option. It seemed to work at first, but it sometimes still throws an error anyway.

For what it’s worth, it is still the most powerful library I found out there, I sent a message of 1mb and it still got through, even in IE7, and its really fast.

That’s it!

Hope this can help you get all your cross-domain communication going!

This piece was written by Cedric Dugas, former Cakemail’s Interface Developer. You can follow Cedric on twitter @posabsolute.

Share this