Hash-Hack for Cross-Domain IFrame Communication

I recently needed a simple, legacy browser (*cough* IE 6) compatible, solution for sending cross-domain communication between an iframe and its parent window. Fortunately, the URL protocol allows changing the hash part of the URL without causing the page to refresh, and the same is true when updating the URL of an iframe. This means that you can use a hash-hack to communicate between the frames.

If you do not need to support < IE 8, the modern technique is to use postMessage to communicate. A full framework would use postMessage when possible, and fallback to the hash-hack technique as a last resort, but this article will only describe the hash-hack technique.

How do it…

We need two pieces of JavaScript, one to be included on the parent iframe and the other to be included on the frame page. To send a message from the parent page, include the following HTML:

<iframe id="idMyIframe" src="{urlForIframedPage}"></iframe>
<script src="{pathToJs}/hashHackSender.js"></script>

And here is how we send a message:

HashHack.postMessage('idMyIframe', 'Data to send');

To receive messages on the child page, include the following HTML:

<script src="{pathToJs}/hashHackReceiver.js"></script>

And here is how we listen for messages:

HashHack.onMessage(function(e) {
    // message is stored on e.data

Below is a little demo showing the hash-hack communication. Change the text and click Send Message, to have it show up in the iframe.

The scripts can be downloaded here:

How it works…

The hash-hack technique uses the hash part of the URL in the iframe to send messages between the parent window and the iframe. This is only necessary if the iframe URL is not from the same domain as the parent window, because normal JavaScript access will be blocked by cross-origin security.

The hashHackSender.js script adds the HashHack object to the global namespace, which has a single function postMessage. Calling postMessage will cause the hash of the iframe URL to be replaced with a formatted message that can be decoded by the hashHackReceiver.js. The postMessage requires the id or element reference of the iframe as the first argument and the message as the second. Keep in mind that we are using a URL to send message, so messages should be relatively short, because long messages will exceed the maximum length of URLs in some browsers (~2000 characters).

The hashHackReceiver.js script also adds the HashHack object to the global namespace, and exposed a single function onMessage. Call HashHack.onMessage, passing a callback function as the only argument, to subscribe to the communication channel. Whenever the hash of the iframe URL is changed and matches a known format, it is decoded and all callback functions will be called. The callback functions will be passed an object with a single data property, containing the message. A simple interval timeout is used to poll for changes to the hash of the iframe.

The goal of this technique is to have one system for communication that can be used on all browsers, including legacy browsers. This is not the most efficient or robust system, but is simple to understand and easy to implement.

There’s more…

There are lots of other strategies for cross-domain iframe communication. This article just focused on a simple, universal technique. For a more complete writeup of various communication strategies and the a list of popular frameworks, see Cross Domain Communications with IFrames.