David Walsh Blog

HTML5’s window.postMessage API

I’ve create a MooTools plugin to wrap window.postMessage: PostMessager. Click here to download it!

One of the little known HTML5 APIs is the window.postMessage API.  window.postMessage allows for sending data messages between two windows/frames across domains.  Essentially window.postMessage acts as cross-domain AJAX without the server shims. Let’s take a look at how window.postMessage works and how you can use it today in Firefox, IE8+, Opera, Safari, and Chrome.

Part One:  The Sender

The first part of the process is setting up a “source”.  With the source, we will open a new window (or IFrame, if you’d prefer to), send the new window message (for the sake of our example, we’ll do so every 6 seconds, and create an event listener for any response we receive from the destination window.


//create popup window
var domain = 'http://scriptandstyle.com';
var myPopup = window.open(domain + '/windowPostMessageListener.html','myWindow');

//periodical message sender
setInterval(function(){
	var message = 'Hello!  The time is: ' + (new Date().getTime());
	console.log('blog.local:  sending message:  ' + message);
	myPopup.postMessage(message,domain); //send the message and target URI
},6000);

//listen to holla back
window.addEventListener('message',function(event) {
	if(event.origin !== 'http://scriptandstyle.com') return;
	console.log('received response:  ',event.data);
},false);

I’ve used window.addEventListener which doesn’t work with Internet Explorer (IE uses window.attachEvent). You’ll want to use a function to normalize event assignment or use MooTools/jQuery/Dojo to do so.

Assuming the window opened properly, we send a message and specified URI match (protocol, hostname, and port, if present) that the destination window must currently be at (because the user may have changed the address of that subsequent window).  If the destination window has changed, the message will not be sent.

We’ve also created an event handler for receiving a message.  It’s extremely important that you validate the event origin when receiving a message because the message handler accepts messages from any URI!  Once the origin is validated, you may handle the provided message in any way you’d like.

Here’s what this looks like when using an IFrame:


//create popup window
var domain = 'http://scriptandstyle.com';
var iframe = document.getElementById('myIFrame').contentWindow;

//periodical message sender
setInterval(function(){
	var message = 'Hello!  The time is: ' + (new Date().getTime());
	console.log('blog.local:  sending message:  ' + message);
	iframe.postMessage(message,domain); //send the message and target URI
},6000);

Be sure to access the IFrame’s contentWindow property — not just the node itself.

Part Two:  The Destination

The second part of the process is getting the destination window ready.  The destination window features an event listener for the “message” event and should validate the message origin.  Again, message events are accepted from any location so it’s extremely important that their origin is validated against a list of trusted origins.


//respond to events
window.addEventListener('message',function(event) {
	if(event.origin !== 'https://davidwalsh.name') return;
	console.log('message received:  ' + event.data,event);
	event.source.postMessage('holla back youngin!',event.origin);
},false);

The sample above sends a response back to the sender to confirm that the message was sent.  There are important event properties:

All three of these components are essential to the messaging system and its validation.

Using window.postMessage

Like every other web technology, there’s obvious danger that this technology could get used improperly if the source is not validated properly; it’s up to you to make your application secure. window.postMessage is like the PHP of JavaScript technologies in that regard (oh, snap!).  window.postMessage is cool though, no?