Html5 Tutorial : Messaging

Resources » Bookshelf » Html5 Tutorial » Messaging

11. HTML5 Messaging APIs

11.1. Understanding the same origin policy

11.2. Workaround to the same origin policy

  • In todays world of open web services and mashups, how can we pass through that security restriction?
  • Currently, popular existing workarounds are:

    • JSONP for JSON (JavaScript Object Notation) with Padding. It has no error handling and not every service implement JSONP.
    • Using a proxy. Since the server is the one making the request to the external service, it makes the whole process slower.

      [Note]Note

      Both of these solutions are not real cross origin messaging.

11.3. Cross-document messaging

  • Cross-document messaging allows document from two different origin to communicate together in a secure way.
  • It is defined in the HTML5 Web Messaging specification: http://www.w3.org/TR/webmessaging/
  • Communication works with messages.
  • The HTML5 Web Messaging specification defines the message event which is used in server-sent events, Web sockets, cross-document messaging, and channel messaging.
  • Among all properties contained in the MessageEvent, two important properties are:

    • data that contains the actual message.
    • origin that contains the origin of the message so we can check if we want to process it or not.
  • We are now going to explain how to send a message and how to process it using the following example:

    • A main window(accessible for instance at http://input.example.com/console.html) containing an iframe(accessible for instance at `http://output.example.com/output.html) accessible.
    • The main window contains a text input along with a "send" button.
    • The iframe will display the message as soon as the "send" button is clicked.

11.3.1. Sending a message

  • For a document A that wants to send a message to document B, a script in document A calls the postMessage() method on the Window object of document B
  • In our example:

    <iframe id="iframe" src="http://output.example.com/output.html"></iframe>
    <script>
      ...
      var consoleOutput=document.getElementById("iframe").contentWindow;
      consoleOutput.postMessage('message','http://output.example.com'); 1
      ...
    </script>

    1

    When sending a message, we need to specify the the receiver origin along with the message to send. The origin of the sender is automatically sent in the message and cannot be spoofed.

11.3.2. Receiving a message

  • To process a message, the receiver needs to register an event handler for incoming messages:

    <div id="consoleOutput"></div>
    <script>
      ...
      function handleMessage(e) {
          if (e.origin == "http://input.example.com") { 1
              var consoleOutput=document.getElementById("consoleOutput");
              consoleOutput.textContent+= e.origin + ": " + e.data + "\n"; 2
          } else {
              // If the message is coming from an untrusted origin, just ignore it :)
          }
      }
      ...
      window.addEventListener("message", handleMessage, true);
    </script>

    1

    When a message is sent, the origin of the sender is automatically included in the message. Here the receiver checks the origin of the sender and only process the message if the origin is a trusted origin.

    2

    As explained before, the message itself is contained in the data property of the message event.

11.3.3. Browser support

  • Cross-document messaging is supported on Chrome 2.0+, Firefox 3.0+, IE 8.0+, Opera 9.6+ and Safari 4.0+

11.4. XMLHttpRequest Level 2

  • The XMLHttpRequest is the main JavaScript API to do AJAX (Asynchronous JavaScript and XML)
  • What is new in XMLHttpRequest Level 2 (http://www.w3.org/TR/XMLHttpRequest2)?

    • We now have the ability to do cross-origin requests!
    • We can now easily implements progress bar thanks to progress events.

      [Note]Note

      XMLHttpRequest Level 2 uses CORS (Cross Origin Resource Sharing): http://www.w3.org/TR/access-control/. This means that both your browser and your server have to support CORS.

11.4.1. Making a request

  • For web developers, Making an XMLHttpRequest level 2 call is not different than before.
  • For instance, a web application on http://www.myfortuneteller.com can access the resource http://fortune.com/tellFortune as follows:

    var client = new XMLHttpRequest();
    client.open("GET", "http://fortune.com/tellFortune");
    client.onreadystatechange = function() { /* do something */ }
    client.send();
  • However, behind the scenes the request headers contain a Origin header so the server knows where does the request comes from (Beware that Origin and Referrer headers are different)
  • For other HTTP methods than GET, HEAD and POST (called simple methods), a preflight request is made to the server
  • The goal of a preflight request is to check if which methods and headers the resource handle and also if the resource supports credentials
  • Let us see an example of what the HTTP request and response look like:

    GET http://anotherdomain.com/script.php HTTP/1.1
    Accept: */*
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: en-US,en;q=0.8
    Cache-Control: max-age=0
    Connection: keep-alive
    Host: anotherdomain.com
    Origin: http://main.html5learning.com:8000 1
    Referer: http://main.html5learning.com:8000/
    User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.107 Safari/534.13

    1

    The origin header specifies where does the request comes from
Access-Control-Allow-Origin:http://main.html5learning.com:8000 1
Access-Control-Allow-credentials:true 2
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:83
Content-Type:text/html
Date:Wed, 02 Mar 2011 05:31:28 GMT
Keep-Alive:timeout=10, max=30
Server:Apache
Vary:Accept-Encoding
X-Powered-By:PHP/5.2.16

1

This response header specifies what origin is allowed to make a request

2

Supports requests with credentials

11.4.2. Progress Event

  • Previous version of the XMLHttpRequest had only one event: readystatechange
  • This readystatechange is inconsistently implemented across browsers
  • Progress bar is not something currently trivial to implements
  • XMLHttpRequest level 2 comes with several new progress events:

    • loadstart
    • progress
    • abort
    • error
    • load
    • timeout
    • loadend
  • This provides the back-end developer a fine control of the XMLHttpRequest

11.4.3. Browser Support

  • XMLHttpRequest level 2 is supported in Chrome 2.0+, Firefox 3.5+ and Safari 4.0+