Html5 Tutorial : Messaging
- Let us first discuss what is an origin: PROTOCOL + HOST + PORT
- The same origin policy has been implemented into major browsers since Netscape Navigator 2.0
- It prevents a document or script loaded from one site of origin A from manipulating properties of or communicating with a document loaded from another site of origin B.
- It prevents attacks like hijacking an existing user session or phishing
For instance, for a URL: http://www.company.com/page.html
URL Same origin? Reason YES
YES
NO
Different host
NO
Different protocol
NO
Different port
Browsers check access against the same origin policy when for instance when we:
- Manipulate browser windows
- Request URL via the XmlHttpRequest
- Manipulate frames (including inline frames)
- Manipulate documents (included using the object tag)
- Manipulate cookies
- 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]](../images/note.png)
Note Both of these solutions are not real cross origin 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
messageevent 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:-
datathat contains the actual message. -
originthat 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.
-
A main window(accessible for instance at
-
For a document A that wants to send a message to document B, a script in document A calls the
postMessage()method on theWindowobject 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');
...
</script>
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") {
var consoleOutput=document.getElementById("consoleOutput");
consoleOutput.textContent+= e.origin + ": " + e.data + "\n";
} else {
// If the message is coming from an untrusted origin, just ignore it :)
}
}
...
window.addEventListener("message", handleMessage, true);
</script>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. As explained before, the message itself is contained in the dataproperty of themessageevent.
- 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]](../images/note.png)
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.
- 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
Originheader so the server knows where does the request comes from (Beware thatOriginandReferrerheaders 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
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
Access-Control-Allow-Origin:http://main.html5learning.com:8000Access-Control-Allow-credentials:true
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
-
Previous version of the XMLHttpRequest had only one event:
readystatechange -
This
readystatechangeis inconsistently implemented across browsers - Progress bar is not something currently trivial to implements
XMLHttpRequestlevel 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