Monday, February 11th, 2008

Cross Window Messaging with HTML 5 postMessage

Category: Browsers, HTML, JavaScript

>John Resig has written a Cross-Window Messaging sample using Firefox 3, which implements the current postMessage API in HTML 5. Opera 9 implements a slightly older version, and a new release will fix that of course:

This particular API adds a new method to every window (including the current window, popups, iframes, and frames) that allows you to send textual messages from your current window to any other – regardless of any cross-domain policies that might exist.

Specifically, you’re given a new window.postMessage(“string”) method that generates a message DOM event on the document of the receiving document. This event object contains the message as a property: event.data which the receiving document can use however they see fit.

His example has a sender:

  1. <iframe src="http://dev.jquery.com/~john/message/" id="iframe"></iframe>
  2. <form id="form">
  3.   <input type="text" id="msg" value="Message to send"/>
  4.   <input type="submit"/>
  5. </form>
  6. <script>
  7. window.onload = function(){
  8.         var win = document.getElementById("iframe").contentWindow;
  9.         document.getElementById("form").onsubmit = function(e){
  10.                 win.postMessage( document.getElementById("msg").value );
  11.                 e.preventDefault();
  12.         };
  13. };
  14. </script>

and a receiver:

  1. <b>This iframe is located on dev.jquery.com</b>
  2. <div id="test">Send me a message!</div>
  3. <script>
  4. document.addEventListener("message", function(e){
  5.         document.getElementById("test").textContent =
  6.                 e.domain + " said: " + e.data;
  7. }, false);
  8. </script>

He also touches on the security issues:

  1. If you’re expecting a message from a specific domain, set of domains, or even a specific url, please remember to verify the .domain or .uri properties as they come in, otherwise another page will be bound to spoof this event for malicious purposes.
  2. Just because a string is coming in, as a message, doesn’t mean that it’s completely safe. Note that in the example, above, I inject the string using .textContent, this is intentional. If I were to inject it using .innerHTML, and the message contained a script tag, it would execute immediately upon injection. This is a critical point: You’ll need to be sure to purify all your incoming messages before they are used and injected into the DOM (or sent to the server). This is the same that you would do on the server-side of your application, be sure to take the same precautions here, as well.

Having a standard, blessed, way to talk using this message based system is going to be great for Web developers.

Related Content:

Posted by Dion Almaer at 6:20 am
2 Comments

++++-
4.2 rating from 34 votes

2 Comments »

Comments feed TrackBack URI

I’ve written a js library that attempts to achieve a very similar concept (alas one cannot implement the same interface). You might want to check it out at http://code.google.com/p/xssinterface/

It needs further testing and might contain severe security holes but it seems to work :)

Comment by Malde — February 24, 2008

it seems to me that one example was left out of the example, sending messages back to the parent.
I have put one on http://ryanday.org i hope it helps someone =). Keep in mind the same postMessage api is used for web workers.

Comment by soldair — August 25, 2009

Leave a comment

You must be logged in to post a comment.