Cross-Domain Communication with IFrames

An update in the era of HTML5 (May 6, 2011)

This post has been heavily commented and linked to over the years, and continues to receive a ton of traffic, so I should make it clear that much of this is no longer relevant for modern browsers. On the one hand, they have adjusted and tightened up their security policies, making some of the techniques here no longer relevant. On the other hand, they have introduced technologies that make it easier to do cross-domain communication in the first place.

With modern browsers, you can and should be using postMessage for this purpose.

Library support is now available too. All of the following provide an interface to postMessage where it’s available, but if it’s not, fall back to the primordial techniques described in this article:

Now back to the original post … (from March 31, 2008)

This article explains iframe-to-iframe communication, when the iframes come from different domains. That you can do this effectively is only now becoming apparent to the community, and is now used in production by Google, Facebook, and others, and has powerful implications for the future of Ajax, mashups, and widgets/gadgets. I’ve been investigating the technique and working some demos, introduced in the article.

Background: Cross-Domain Communication

Ironic that in this world of mashups and Ajax, it’s not very easy to do both of them together. Ajax applications run in the browser and such applications were never intended to talk to anything but the server from whence they came. So it’s not easy to mash content from multiple sources, when everything must be squeezed through the originating web server. A few hacks have arisen over the years to deal with this, such as On-Demand Javascript, and the most recent one is a hack involving iframes, which I’ll explain in this article. As we’ll see later, the iframe technique is arguably more secure than On-Demand Javascript, and it’s also better places for communication within the browser, i.e. from one iframe to another.

Related to this article is a demo application and a couple of variants.

The first mention I’ve seen of this hack originated on James Burke’s Tagneto blog in June, 2006, though I’m fairly certain it’s been used in some quarters long before that. It’s now used in production by Google in Mapplets. It’s also used in Shindig for widget-container communication. The technique also happens to be the best way to make safe cross-domain calls from the browser directly to a third-party server, which is why it is employed by Facebook’s new Javascript Client Library.

The Demo

First, let’s see what we can do with this hack.

Demo

In this demo, we have a control on the top-level document affecting something in the iframe and vice-versa. This shows you can run communication in both directions with this technique. Typical of the technique, the communication is between two browser-side components from different domains (as opposed to browser-to-server communication, although there is actually server communication involved in making this happen).

The Laws of Physics: What you can do with IFrames

To understand the hack, we need to understand the “laws of physics” as they apply to iframes and domain policies within the browser. Once you appreciate the constraints in place, the pattern itself becomes trivial. This demo was created to explore and illustrate these constraints, and contains some simple code examples.

Definition I: A “window” refers either to an iframe or the top-level window (i.e. the “main” page). In our model, then, we have a tree-like hierarchy of windows.

Law I: Any window in the hierarchy can get a handle to any other window in the hierarchy. It doesn’t matter where they live within the hierarchy or which domain they come from – with the right commands, a window can always refer to any other window. Parent windows are accessed as “parent”, “parent.parent”, etc., or “top” for the top-level. Child windows are accessed as “window.frames[0]” or “window.frames[name]“. Note in this case that the name is not the iframe’s id, but rather the iframe’s name. (This reflects the legacy nature of all this stuff, relating back to ugly late-90s frames and framesets.) Thus, to get a sibling handle, you might use “parent.frames[1]“.

Law II: Windows can only access each others’ internal state if they belong to the same domain. This rather puts a kibosh on the whole cross-domain cross-iframe thing. All this would be so easy if iframe scripts could talk to each other directly, but that would cause all manner of security shenanigans. HTML 5 does define explicit communication between iframes, but until wide adoption, we have to think harder …

Law III: Any window in the hierarchy can set (but not read) any other window’s location/URL, even though (from Law II) browser security policies prevent different-domain iframes from accessing each other’s internal state. Note: Exact details for this law needs further investigation Again, it doesn’t matter which domain it comes from or its position in the hierarchy. It can always get a handle on another window and can always set the window’s URL, e.g. “parent.frames[1].location.href”. This establishes window URLs as the one type of information on the page which is shared across all windows, regardless of the domain they come from. It seems sensible that a parent can change its child windows’ URLs, BUT not vice-versa; how strange that a child window is allowed to alter its parent’s (or uncle’s, sibling’s, etc.) URLs! The only justification I know of is the old technique of escaping the frame trap, where a website, upon loading, ensures it’s not inside a frame by simply setting the top-level URL – if it’s different to itself – to its own URL. This would then cause the page to reload to its own URL. However, that’s a special case and hardly seems worth justifying this much leeway. So I don’t really know why you can do this, but lucky for us, you can!

Law IV: When you change the URL’s fragment identifier (the bit on the end starting with a #, e.g. http://example.com/blah#fragmentID), the page doesn’t reload. This will already be familiar to you if you’re familiar with another Ajax hack, Unique URLs to allow for bookmarkability and page history. Normally, changing a document’s “href” property causes it to reload, but if you only change the fragment identifier, it doesn’t. You can use this knowledge to change the URL symbolically – in a manner which allows a script to inspect it and make use of it – without causing any noticeable change to the page content.

Exploiting the Laws of Physics for Cross-Domain Fun and Profit – The Cross-Domain Hack (URL Polling version)

The laws above are all we need to get cross-domain communication happening. The technique is simply this, assuming Window A wants to control Window B:

  • Window A changes Window B’s fragment identifier.
  • Window B is polling the fragment identifier and notices the change, and updates itself according to the fragment identifier.

Ta-da!!! That’s the whole thing, in its glorious entirety. Of course, you had to know the laws of physics in order to understand why all this works. It simply relies on the fact that both Window A and Window B have one common piece of state – the URL – and the fact that we can change the URL unintrusively by manipulating only the fragment identifier. For example, in the demo, the iframe’s URL changes to http://ajaxpatterns.org/crossframe/#orange and once the iframe script notices it, it updates the colour.

A few observations:

  • This works in either direction. Parent to child, child to parent. As the demo illustrates.
  • It requires co-operation from both parties; it’s not some magic way to bypass browser security mechanisms. Once Window A changes Window B’s fragment identifier, it’s up to Window B to act on the change; and it’s up to Window B to be polling the fragment identifier in the first place.
  • Polling the fragment identifier happens to be exactly the same technique used in the Unique URLs pattern.

There are a couple of downsides: (a) Polling slows down the whole application; (b) Polling always involves some lag time (and there’s always a trade-off a and b – the faster the response, the more cycles you application uses up); (c) The URL visibly changes (assuming you want to manipulate the top-level window). We’ll now consider a second technique that addresses these (albeit in a way that introduces a different downside).

The Cross-Domain Hack (Marathon version)

Here’s a variant which no longer involves polling or changing any URLs. I learned of it from Juliene Le Comte’s blog, and he’s even packaged it as a library.

Looking back at Law II: “Windows can only access each others’ internal state if they belong to the same domain”. At the time, I made this sound like a bad thing, but as David Brent likes to say, “So, you know, every cloud …”. The law is bad if you state it as “cross-domain iframes can’t play with each others’ toys” (paraphrasing the informal version of Demeter’s law). But it’s good if you spin it as “well, at least same-domain iframes can play with each others’ toys”. That’s what we’re going to exploit here.

As for the demo, the functionality is the same, but since this one involves spawning iframes, I’ve left them intact, and made them visible, for your viewing delight. Normally, of course, they’d be invisible, and the application would look exactly the same as the previous demo.

Here’s how this technique works:

  • Every time Window A wants to call Window B, it spawns a child iframe, “Window B2″ in the same domain as Window B. The URL includes the command being issued (as a CGI parameter, fragment identifier, or any other URL pattern which will be recognised by the destination script).
  • When window B2 starts up, its Javascript inspects the URL, gets a handle on Window B, and updates Window B according to the URL (e.g. a CGI parameter).
  • Window B2 destroys itself in a puff of self-gratified logic.

So in this case, we create a new, short-lived, iframe for every message being passed. Because the iframe comes from the same domain as the window we’re trying to update, it’s allowed to change the window’s internal state. It’s only useful to us on startup, because after that we can no longer communicate with it (apart from by the previous fragment identifier trick, but we could do that directly on the original window).

Window B2 is sometimes called a proxy because it accepts commands from Window A and passes them to Window B. I like to think of it as Pheidippides of fame; it passes on a message and then undergoes a noble expiration. Its whole mission in life is to deliver that one message.

This technique comes with its own downside too. Quite obviously, the downside is that you must create a new iframe for every call, which requires a trip to the server. However, with caching in place, that could be avoided, since everything that must happen will happen inside the browser. So it would simply be the processing expense of creating and deleting an iframe element. Note that the previous variant never changed the DOM structure or invoked the server.

Also, note that in either versions of the hack, there is the awkward matter of having to express the request in string form, since in either pattern, you are required to embed the request on the window URL. There is an inspired extension of this hack that also has some untapped promise in this area. It involves setting up a subdomain and updating its DNS to point to a third-party website. When combined with the old document.domain hack, you end up with a situation where your iframe can communicate with a cross-domain iframe, without relying on iframe. (The technique described in the article is about browser-to-server communication, but I believe this iframe-to-iframe is possible too.)

A Third Hack Emerges: Window Size Monitoring

A newer third hack by Piers Lawson is based around the porous nature of window sizes and the use of window.resize(). Fragment IDs are used like in the first technique here, but instead of polling, window resize events are used to cause a more direct trigger.

Applications

Cross-Domain IFrame-to-IFrame Calls … and Widgets/Gadgets

In the world of mashups, iframes are a straightforward way to syndicate content from one place to another. The problem, though, is limited interaction between iframes; in pure form, you end up with a few mini web browsers on a single page. It gets better when the iframes can communicate with each other. For example, you can imagine having iGoogle open, with a contacts widget and a map widget. Clicking on a contact, the map widget notices and focuses on the contact’s location. This is possible via Gadget-To-Gadget communication, a form of publish-subscribe which works on the iframe hack described here. And speaking of maps, check out Google Mapplets, which are a special form of gadget that work on Google Maps, and also rely on this technique.

In terms of gadgets, another application is communication between a gadget and its container, and this is something I’ve been looking at wrt Shindig. For example, there is a dynamic-height feature gadgets can declare. This gives the gadget developer an API to say “I’ve updated, now please change my height”. Well, an iframe can’t change its own height; it must tell its parent to do that. And since the gadget lives in an iframe, on a different domain as the container (e.g. iGoogle), this requires a cross-domain, cross-iframe, message. And so, it uses this technique (“rpc” – remote procedural call – in shindig terminology) to pass a message to the container.

Cross-Domain Browser-to-Server Calls

The best known technique for calls from the browser to an third-party server is On-Demand Javascript, aka Javascript APIs aka JSON/JSONP. This was obscure in 2005, with Delicious being the best example. Now, it’s big time in Web 2.0 API land, and Yahoo! has exposed almost all of its APIs this way, and Google also provides data such as RSS content via JSON.

It works by spawning a new script element programmatically, an element pointing to an external Javascript URL. Since there’s no restriction on third-party Javascript running, the browser will faithfully fetch and execute the script, and so the script will typically be written to “return” by updating variable and/or calling an event handler.

There are two major security issues with On-Demand Javascript. Firstly, you have to trust the API provider (e.g. Yahoo!) a lot because you are letting them run a script on your own web page. And there’s no way to sanitise it, due to the script tag mechanism involved. If they are malicious or downright stoopid, your users may end up running an evil script which could ask for their password, send their data somewhere, or destroy their data altogether. That’s because whatever your web app can do, so can the third party’s script, even if you’re only trying to get a simple value back. The mechanism forces you to hand over the keys to the Ferrari when all you want is a new bumper sticker. Secondly, what’s to stop other websites also making use of the external Javascript? If your own site can embed the script to call a third-party JS API, so too can a malicious fourth-party. This is fine for public, read-only, data, but what if you’re relying on the user’s cookies to make privileged calls to the third-party? Then the fourth-party’s web app will be just as capable of issuing calls from the browser to the third-party, and they might well be more evil calls than you’re making, e.g. “transferFunds()” instead of “getBankBalance()”. The moral is: Javascript APIs can only be used for serving public data.

Whoa!!! Public data only? That’s a tragic restriction on our cross-domain API! For mashups to be truly useful, it must be personal. We’ll increasingly have OAuth-style APIs where users will tell Site X that Site Y is allowed to read its data. But how can that work in the browser? How can Site Y expose its data so that it’s usable from the browser, but only when Site X is running? It can’t work with On-Demand Javascript. Site Y could try reading the referrer headers to see where the call is coming from, but anyone could write a command-line client with fake headers.

In fact, the answer is to use the iframe hack described in this article. As I mentioned earlier, this is how Facebook gets the job done, with what is essentially the same “power of attorney” delegation model as OAuth (BTW thanks to my colleague Jeremy Ruston for the “power of attorney” OAuth analogy – albeit it was stated in a slightly different context from OAuth).

I haven’t looked too much into the mechanism involved with the Facebook API, but it looks like it’s essentially using a variant of the Marathon technique. From memory, there’s an ever-present invisible facebook.com iframe. Each time your web app make a Facebook call, the Facebook JS library spawns a new “proxy” iframe, which passes the message on to its same-domain ever-present frame, which makes a bog-standard XHR call to Facebook. So now we’re making an XHR call to another domain, which we can get away with because it’s coming from a separate iframe. Once the XHR call returns, I think the message is returned to your application (this happens via another same-domain iframe you must host on your server, though I think that’s unnecessary) and the proxy iframe disappears.

Note that all Facebook ever exposes is a standard web service that relies on the user being logged into Facebook – there’s no Javascript involved. The user must be logged in and must have given permission for the application to access its Facebook details. Effectively, the user is allowing a particular website URL to make Facebook calls, since the application developer must register the URL. If you look back at the iframe algorithms I described earlier, you’ll see that it’s straightforward for Facebook to ensure that only this application (and any other application the user trusts) can access the data. The Facebook.com iframe (whose behaviour is controlled by IFrame and can’t be tampered) simply has to inspect the URL of the parent window and pass it to the server as part of the XHR call. The server can then check that the logged-in user has authorised this application, using the URL to identify it.

As for the first concern of cross-domain Javascript – having to trust the third-party API provider – I believe the iframe technique overcomes this concern too. Facebook.com never gets to run arbitrary Javascript on your server. Of course, you have to trust the Facebook library and the Facebook-provided iframe you’re required to host on your domain, but those could be audited prior to installation. All those things are set up to do is call callback methods inside your top-level application; you could inspect the library and ensure that’s all that will ever happen.

Thus, cross-domain iframe-based communication solves both problems which have plagued On-Demand Javascript. It is slightly more complicated, however.

Conclusions

Yes, this is a somewhat complicated technique. Actually understanding the problem it solves is really the hard part! Once you understand that, and once you understand those laws of physics, the trick is actually quite straightforward (either version of it).

The technique will be critical for gadget containers such as Shindig. As OAuth takes off, we’ll also see the technique used a lot more in mainstream applications and APIs.

With HTML 5, cross-frame messaging will render the hack unnecessary for iframe-to-iframe communication. Indeed, the aforementioned Cross-Domain library uses that technique already for Opera, in a fortuitous twist of fate since Opera doesn’t actually support everything this hack requires. However, the notion of using iframes for cross-domain calls will still be present, no matter how the windows talk to each other.

123 thoughts on Cross-Domain Communication with IFrames

  1. Hi – thanks for a great article! We are trying to do just that . we need to READ the location.href of one iframe (from domain a, not our domain) from another – but can’t!

    According to this MSDN article, http://msdn.microsoft.com/en-us/library/ms533028(VS.85).aspx “…document.location.href Property can be set to navigate, but cannot be read….”

    but that goes against your third law…

    Any idea what could we be missing?

    thanks very much again Lior

  2. Lior, thanks for the comment. Someone else pointed out something similar and I’ve updated the law accordingly.

    In the case of the guy who contacted me, he could still solve his problem by other means. The two iframes can still communicate with each other using the techniques described here, so there’s always a way for them to pass their URLs to each other, or any other info.

  3. Pingback: Silenceway

  4. Unfortunately child to parent communication no longer seems to work on Safari 3 on Mac and the Javascript error console reports “Unsafe JavaScript attempt to access frame with URL”. Parent to child still seems to work OK though.

  5. I’m new to Javascript, but would this be an appropriate solution for doing something fairly simple like, replacing a stylesheet for a page over which I have no control?

    I am loading an external page in an iFrame, and would like to make some style changes to the page, but have had no luck. Would this technique allow me to do that?

  6. Pingback: Explaining the “Don’t Click” Clickjacking Tweetbomb

  7. This article is an interesting and very thorough read on this topic. I appreciate knowing with a good explanation what the iframe proxying details are all about in the minute detail.

    I think however that it’s a pretty elaborate workaround for cross-domain communication. The following negatives come to mind:

    1. iframes (in IE) use a lot of memory, especially as you generate a lot of them dynamically and kill them off (the garbage collection doesn’t always clean up all of an iframe’s usage). So, as a page lives longer, this seems like this techinque will end up consuming a lot of browser memory, and probably slowing things down.

    2. timers/polls/intervals are definitely helpful, but if they have to run constantly in a page (not just used for short durations, like in aminations), they really slow down a page’s responsiveness.

    3. I don’t see that the technique you mention (which facebook uses!) really guarantees that an app can opt-in (or out) of allowing such an elaborate “evil” site to take advantage. The reason is, in javascript, you can overwrite properties/functions dynamically. So for instance an evil page could fool the iframe proxy into sending along a domain (which is known to be trusted), even though that’s not the actual page domain in the browser.

  8. Inside the iframe: parent.window.location.href = “xyz.com” wasn’t allowed by IE7, but it appears that: window.parent.location.href = “xyz.com”; works like a champ.

    thanks for the post.

  9. hey guys,

    the first demo where you can change the speed and colour of iframe. Is this demo only using crossframe.js. I don’t where util.js ajaxCaller.js are been used. Am I missing something here. ??

  10. @gary laird, those other libs aren’t used (I haven’t checked, but I’m fairly certain). The demo is based on the simple, hand-built, framework for all the demos I use on ajaxify, which pulls in utils and ajaxCaller by default.

  11. Pingback: Cross-Domain Calls with IFrames « Sandip’s Programming Zen

  12. Nice to see an old trick be revived. I used that almost 10 years ago, when Ajax was not existing (to query a server and display dynamical stuffs like ajax do). Just check the website, the result page use that trick.

    Furthermore, as the iframe get data from a 3rd party site, you can simply scrap it (JS or server side), then do a mix with existing/orther 3rd party datas. But that is nothing new, I do used that before Y2000.

  13. Just used your test page, saddly it did nto work.

    My 2 cents, and I will not make the insult to give you the solution, is it might be relatedto the fact you process your various JS localy (read within the various iframes) instead of grouping them to the main window (parent) . Datas are local but processing have to be global to avoid the various security protections exising (IE7 for exemple).

    Hope it make sense, and hope you can fix the broken demo

    cheers mate

  14. Thanks for your suggestion @Sting01. Realistically, I won’t have time to revise the demo for a while at least, though someone else could grab it and try it. It’s good to know there are fixes for IE7 and beyond.

  15. Pingback: Cross Domain AJAX Calls and Iframe Communication How To | Life Scaling

  16. Pingback: www@www » Cross-domain Communications with Iframes by Michael Mahemoff

  17. Pingback: links for 2009-07-14 « BarelyBlogging

  18. Rocco, I haven’t looked into specific browsers, but it’s true – the browsers have become stricter about windows sniffing each other’s sources. There are possibly workarounds (like switch the direction of the sniffing – others above have suggested it still works in one direction).

  19. window.name might be one workaround, as a global shared by all windows, but is probably also going to be unsupported by browsers in the future, and might be accessed by other windows (those also open on the page and those to be opened after the user clicks on a link).

  20. Pingback: Ajaxian » Cross domain iframe communication without location polling

  21. Pingback: Cross domain iframe communication without location polling | Guilda Blog

  22. Pingback: The Ashes » Blog Archive » Cross domain iframe communication without location polling

  23. Pingback: Cross domain iframe communication without location polling « LocalLab : Foire aux Infos

  24. This seems to require access to the code on both the parent page and the iframe’s page. What if the iframe is from an external URL which you can’t put JS into? Then it’s back to the permission denied errors. Or am I misunderstanding the whole thing?

  25. Kam, this is indeed the right kind of stuff you need to use in order to do that, ie have an iframe tell its parent to resize.

    You might try some of the libraries that are emerging in this area – I haven’t looked at them in detail, but I suggest googling for “cross-domain library” and the like.

  26. Wow, this is very recent.

    I didn’t know you couldn’t READ other iframes’ URLs. So it seems to me that the resizing technique is the cleanest. No timers, no creating iframes. DOES IT WORK IN ALL THE MAJOR BROWSERS? Can anyone tell me? Surely if facebook uses something similar…

  27. Another BIG downside of using the location hash to send message t0 the parent window is that it adds an entry to the browser history each time the hash changes.

    In AJAX applications it is a good thing, but not in a cross domain iframe communication because it screws up the back button behavior.

    If someone knows a way to do it whitout modify the browser history please let me know ! Opera and IE6-7-8 don’t modify history, only FF, GG chrome and Safari do it :/

  28. Pingback: A jQuery text extractor (via Java proxy) « Eltit Golb

  29. Hi,

    Great article. I’ve been wrestling to cross domain iframes, and i think i’m losing. I was hoping to get some info after reading your post. Essentially what i’m trying to do is i’m opening a new window that has content hosted on another domain. within that content there’s an iframe which is content on the same domain as the popup, and in that iframe i have links that refer to the opener of the popup. the problem i’m having is when i click one of the links, instead of opening the link in the window’s opener it opens a new window, or tab instead of the opener.

    is what i’m trying to accomplish even possible? It sound fairly trival, but i’m not having luck.

    Thanks, John

  30. Pingback: Weekly Link Roundup – November 21, 2009 « Technosiastic!

  31. If you need to fetch something from an iframe which is on other domain there is a simple way. It works for me in IE7 and FF2. I suppose it will work in newer browsers, but try it yourself. Just set document.location.href = document.location.href + “#data”; inside the iframe, and fetch that outside by parsing document.getElementById(‘iframeID’).contentWindow.location.href Inside this you will have your data after the hash symbol. Fetch it and use it!

  32. We’ve been wrestling with this problem too. We have an application (A, domain a.xyz.com) which would like to display only a small portion of the data created by a legacy app (B domain b.xyz.com). B exposes its data via HTML, and can easily be placed in an iframe, but the results are ugly.

    We attempted to make peace using Law II, using javascript we would tell both pages they were the same domain:

    The developers of B were willing to place a small piece of code on their page, so long as they didn’t have to tangle with the data. We asked for the script document.domain=xyz.com Then, on A, we did the same.

    I’m not sure if you have any insight on this, but I’m posting it in the hopes it will help others (you are not alone). Meanwhile, I’m off to try other approaches.

  33. Pingback: links for 2009-12-11 « Caiwangqin’s delicious bog

  34. I am sick of this cross domain issue. duhhh… i have a page which has 2 iframes , but the href of both the iframes are in different domain. what i need to set a hash from one iframe to the other. i tried all the methods you guyz posted above but none of these are working. could you please help me on this.?

  35. Pingback: Unintended Consequences and the Inevitable “Why Would Anyone Want To Do This?”

  36. Great article. I’ve been working with OpenSocial and Facebook for awhile, and while they support cross-domain iframes, it’s always been unclear as to what exactly is going on. Thanks for the explanations.

  37. Your well written article provides a solid conceptual foundation rarely found in the world of cyberhelp as well as “hope” for the future. Thanks!

    I do have one question pertaining to a specific situation.

    I have a project in the works, which ultimately would be a fb app, but for now is still in my java editor.

    It has among others things a fb iframe primarily so that I can see what i am styling. When I am finished, I will flip it around so that the fb page is the main page and everything else is in a iframe.

    Everything was fine for a week or ten days, then a day or two ago, I noticed that the equivalent of a “opacity screen” (dark gray about 15%) was over the iframe in question after log-in to the that iframe.

    I have over 1000 lines of code and no reference to layer, opacity, filter, focus or anything remotely connected to the problem at hand.

    Could it be that it originates in the source?

    Somehow, I am thinking that your article answers this question in a general way, but I am looking for a more specific answer.

    Thank in advance you for your prompt reply.

    In the meantime, I going to go see if you have written anymore articles of similar quality.

    Best Regards, g

  38. Pingback: Hiding empty ad slots with cross-domain iframe scripting | Autoedification

  39. I’ve been doing this for 8 years, too. Both for cross-domain and for page update sans refresh. If you can stomach it, you can use a frameset and zero-sized frames. This helps avoid the iframe IE7 issues, but kills non-3g/4g mobile users.

  40. (comment manually re-inserted by @mahemoff after blog migration)

    If you want to do this the easy way you should use easyXDMhttp://easyxdm.net/, which makes it ‘extremely’ easy to add cross-domain scripting (including RPC and AJAX) to applications. It takes care of all the security precautions, handles cross-browser issues (yes it supports IE6) and gives you a simple abstracted interface to work with. Full two way communication can be done with as little as 5 lines of code!

  41. I just re-read the last section of the article, and relized that easyXDM fits perfectly here.

    easyXDM is based on a separate document being loaded from the provider (the foreign domain), and can provide all the authentication needed there.

    The origin of the local domain is also provided, and so the provider can actually enforce authorization.

    There is actually a demo showing how to perform XHR against a 3′rd party at http://consumer.easyxdm.net/current/example/xhr.html

  42. Great explanation of this, I actually came looking for a ‘how’ after seeing this google gdata video: http://www.youtube.com/watch?v=ZvFVs92Fydw

    However I still feel these hacks (jsonp, iframe, etc) are all such horrible pains, I want to transfer binary data from page on domain1 -> server on domain2 without having the huge overheads of serialisation (to / from strings / json) and the overhead of creating dynamic html objects (script tags, iframes, etc).

    Give me cross domain XHR!!!!!!

    Thanks for a great article.

    Guido

  43. You said “The Facebook.com iframe (whose behaviour is controlled by IFrame and can’t be tampered) simply has to inspect the URL of the parent window and pass it to the server as part of the XHR call”.

    How is this possible? The location object in a parent frame from a different domain is not accessible to the FB frame…

  44. Hi, the method with the fragment identifier seems to only work in Firefox (both your demo, and my own implementation of it). Is there any method that will work in IE and Chrome as well?

  45. Ok, not what I’d hoped for (in the Demo):

    • Chrome 5.0.375 reports “Unsafe JavaScript attempt to access from with URL…”.
    • IE6, 7 & 8, Access denied
    • Opera 9.63, fail
    • Safari 5.0, fail
    • Firefox 3.5, Works fine

    All attempts to change the colour of the iframe background were successful. All failed attempts arose when trying to change the speed.

    WinXPPro, SP3 [email removed by request -MM]

  46. Gidday moderator, sorry, could you please remove my email addy from my last post? :P

    It was copy/paste leftovers from my comment in your ‘in development’ RSS feedback form on the Demo page.

  47. Good stuff, but should really be updated: 0) Your policy information is wrong, the demo is broken. Please correct this – at current it is confusing to your readers, and this is a highly ranked page! Browsers can only change the policy of their descendants, as you suggested yourself. See http://seclab.stanford.edu/websec/frames/navigation/ Though, IE6 and Chrome4 don’t match 100% in my tests.

    1) Assuming interchange over hashUpdate, one could now use the hashChange event instead of poling or resizing – its supported by every current browser. 2) Which is good, as some of these hacks [such as the resizing in Webkit] are broken. 3) There are other methods you have not discussed to take its place, but: 4) However, the correct way to do this is with message posting, which enjoys even wider support than the hashchange [opera 8+, IE 8+, FF 3+, Chrome 1+ / Safari 2+] .

    I have a mootools class in the works, and there are a few good libraries that deserve mention.

  48. Hi ,

    I am having the same issue with iframes -cross domain..Is anyone able to solve this issue?

    Basically we are sending a reuest from http://abc.com to call iframe in http://xyz.com and it is giving “Access denied error”

    Appreciate your reply..You can send an emaill.Thanks

    Gop

  49. Pingback: Strophe and Greasemonkey « NoTube blog

  50. The part that I did not get from the explanations above is how you create the short-lived iframe once the Go button for changing the color is clicked. I looked at the source code but I can’t find the part where the iframe is created. Can you clarify this with some code example? Thanks!

  51. @ToddySM, just create it as you’d create any other child element.

    iframe = document.createElement(“iframe”); iframe.src = “http://otherdomain.com/marathon?color=blue”; document.body.appendChild(iframe);

  52. @mahemoff, thanks! I couldn’t find this in your code. However I am still struggling with the problem that I need to solve. Briefly I am trying to capture a click in the IFrame however I don’t have control of the IFrame content and even less on the domain. Any suggestions?

  53. If you don’t have control over the iFrame, I don’t think it’s related to cross-domain messaging, because you can only do that if both domains give consent. (And hence you – or your “friend” – has control over the other domain you’re embedding.)

    Basically, you can’t capture a mouse click from another domain or do anything with its content. A hack is to put an absolute-positioned, transparent, element in front of the iframe and capture clicks from that. (The basis of the clickjacking attack.) However, it’s not practical as you don’t have control over where elements in the iframe appear or scrolling.

  54. Hi, thanks for this guide. But there is one think i don’t understand.

    “Window B2 destroys itself in a puff of self-gratified logic”

    How is this possible? I have to wait until B2 is fully loaded, but B2 can’t tell his parent it’s status.

  55. Pingback: Native Javascript Ninjutsu: DOMinating iframes « sociomantic labs

  56. Pingback: Including HTML Files from Other HTML Files, on the File:// System

  57. Pingback: Blog network widget vs. Internet Explorer | Madison.com Labs Blog

  58. Pingback: HackerNews submit button: e stamattina me lo sono fatto da solo | Silvio Porcellana

  59. The URL polling hack for child to parent frame communication does not work in Internet Explorer 8. Permission/Access is denied to parent.location.hash.

    Because I only needed to send result data to the parent frame (selection of a location on a google map), I let the page in the child frame (on another domain) redirect to a page on the domain of the parent (still within the iframe) with the result data in the querystring. This page is allowed to access the parent, so it can invoke a JavaScript function in the parent with the result.

  60. I was happy to see that your “Sniff URLs” demo button worked fine. . . and then disappointed to see that it was all within one domain.

    If all the iframes in your demo were from different domains, I don’ think “Sniff URLs” would work. Am I correct that this is impossible?

  61. Pingback: Lee Unlikes Facebook Programming « Playful Programming

  62. I was just trying out some cross-domain stuff using the suggestions here but found that I was stopped with Law 1 not being true in Firefox 3.6.13 on OS X 10.6.6. JavaScript in an iframe loaded from a different domain has no access to it’s parent window (ie. parent is undefined). If a change the code to use the same domain then it all works. Any suggestions?

  63. Passing sensible data trough hash withouth being able to verify the location of the target window, introduces a horrible lack of security. Or did I misunderstand something.

  64. I came up by this myself by thinking for a few minutes a few months ago and hacked out an example which worked! Glad to see you have given it a more thorough treatment

  65. Hi, I was looking for a source about XD access with iframes, your blog was very good, but what really surprised me was the photo of Habana!, had to look twice!I thought initially it was a very targeted ad…

  66. You should really post something on the top that says this doesn’t work on all modern browsers. I wasted a lot of time trying to implement the polling technique in chrome. :(

  67. Hi -

    Interesting article, however, it didn’t work for me (albiet, I am a very rusty web developer!). Just posted this on Stackoverflow and am hoping you may be able to shed some light. In short, I have an iframe which may contain a src from almost any external domain. I want to be able to highlight text in the iFrame and drag it to a “droppable” element in my parent page. Here’s my Stackoverflow question, in case you can help:

    I am building a web application with a requirement to allow users to drag text from an iframe (src could be from any external domain) to a droppable element in my parent window. While I can easily get a handle on the iFrame window, I get the expected security errors when I attempt to select data from within the iFrame.

    Currently, I am playing around with code copied from a Mark Kolich post on his website. I have modified it to look for selected text in an iFrame. I have tried modifying the URL fragment (i.e., adding “#crunch” to the end of the URL) based on what I read here: http://softwareas.com/cross-domain-communication-with-iframes

    … but it doesn’t seem to make a difference. I haven’t moved beyond simply trying to get hold of the selected text, yet.

    Is there a way to capture text highlighted inside an iFrame (pointing to an external domain) so that it can be dragged to an element on the parent window?

  68. Pingback: Quora

  69. Pingback: Strophe and Greasemonkey | NoTube

  70. Pingback: REST Communication with Ajax jQuery: a Bumpy Road | rassembling bits

  71. Pingback: The iframe cross-domain policy problem | Skyowner.com Blog

  72. Hi , i m having problem in calling IFrame which is using cross domain contents, basically what i have to do is that there’s a authentication page on my website and it should authenticate to another 3rd party website, and after successful login it should display on the IFrame of my website. I tried to pass the credentials through querystring from my website to 3rd party site, and successfully it gets login and displaying their content after login, but as i have to display the contents inside the iframe in my website so it doesn’t work for it.

    Please help me out, my head is spinning by trying numerous way to solve it but invein , i m newer to development.

  73. Unfortunately the fragment hack doesnt work in IE (tested IE7 and IE8 so far). Permission denied (Microsoft as always looking for better ways to make a developers life miserable). I also used the nested iframes technique, but since I need the initial url to be passed to the parent->child->child (parent) iframe, I need cookies, and IE decides, for the first time in their lives, to follow the P3P standards, so cookies are disabled unless the server send the P3P headers (there goes that hack). Anyone has any ideas? I’ve tried five different things (each one work in all browsers, except IE of course) and still stuck with the same origin policy.

  74. Pingback: Cross-Domain-Ajax POSTs mit JSONP und IFrames » evermind Blog

  75. Wow Disqus comment spam… Any rate, great article. It cleared some things up for me, even if some of the content is as you say a few years old. The window.postMessage and the subsequent jQuery plugin was a great referral.

  76. Pingback: Eyelock» A Simple Cross-Origin Resource Sharing Example Explained

  77. I have an iframe being created on a page, and the page’s domain is being explicitly set to ‘xyz.com’ but the iframe’s domain is defaulting to ‘dev.xyz.com’, which is the actual domain i’m developing for.

  78. Pingback: Cross Domain AJAX Guide | David Müller: Webarchitektur

  79. Pingback: ??????????? ?? ?????????????? AJAX`? - ???? ???????? ????????

  80. Pingback: [?]WEB?????? « ??

  81. Pingback: Hello world! | Ramesh's Blog

  82. Hi,

    I need a clarification, i have a link in my site. that opens an iframe inside someother domain(that is also my site only). Can i change parent div class of iframe from my second domain code?

    example:

    domain1 domain2 – here if i write i code, can i add class parent div??

    reply asap.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>