One of the most interesting things to me that HTML5 has introduced is the XMLHttpRequest Level 2, and more specific the cross-origin requests.
Up until now the browser vendors enforced cross-origin requests due to security reasons. The only way for a web page to talk to another web page outside of its domain was either to use all kind of black magic XSS, or to use browser plugins, like greasemonkey.
Now, thanks to the Cross-Origin Resource Sharing (CORS), you can talk to web pages outside your origin.
Web Origin
An origin is a subset of the URL address. Origin is made up from the scheme (http or https…) the host (www.amirharel.com) and the port (8080). So, for example the followings are all different origins:
- http://amirharel.com
- https://amirharel.com
- http://blog.amirharel.com
- http://amirharel.com:20
On the other hand, origin ignores the URL path so all these URLs has the same origin:
- http://amirharel.com/test/domsomthing.html
- http://amirharel.com/test2/dommorestuff.php?param1=user¶m2=pass
HTML5 will use this origin in several APIs, like the postMessage and the WebSockets.
Talking to a stranger
Whenever you will try to make a request to a page outside of your origin, the browser will add to the request header the origin of your page and will wait to see if the server authorize your request.
Actually, the CORS specification request that for sensitive actions an OPTION pre-request must be sent to the server by the browser to see if the action is supported and allowed. So, the browser will send an additional OPTION request and will wait to see if the server recognize the origin as an authorized request.
Let’s see an example headers:
Request header
POST /main HTTP/1.1
Host: www.amirharel.com
User-Agent: Mozilla 5.0
Referer: http://www.amirharel.com/
Origin: http://www.amirharel.com
Cache-Control: no-cache
Response header
HTTP 1.1 201 Created
Transfer-Encoding: chunked
Date: Mon, 24 Jan 2011 07:00:00 GMT
Content-type: text/plain
Access-Control-Allow-Origin: http://www.amirharel.com
Access-Control-Allow-credentials: true
Building an AjaxStore
This CORS opens up new and interesting concepts for front-end development. The most important one to me, is the ability to shift more logic and computation to the client from the server. If up until now we required to fetch some data from a third party vendor , we had to do it using our servers due to the cross-origin limitations. Sometimes it make sense to allow the server to do this kind of work, but sometime it only becomes a bottle neck and burden the server with tasks it doesn’t really have to do.
My front end philosophy is “Less-Server Please” , which means that whenever we can and it makes sense, shift logic from the server to the client, and to make servers as light and efficient as possible. I just think of it like this: you already have users – let’s use their CPU!
Up until now implementing this philosophy was possible within the origin of your site. Yahoo introduced some interesting concept with YQL to allow you to query web sites out side of your origin from the client side, but I’m not aware of big players used that service with production sites.
Anyway, with the XmlHttpRequest level 2, it’s possible, as long as the server support it by sending these headers back.
We all know about the concept of web services , which introduced us with all kind of bad words, like “WSDL” and “SOAP”. This concept of web services is now available to client side as well, as i call it – the AjaxStore.
The AjaxStore concept is less interesting to me to develop (since its a server side development) rather more interesting to consume as front-end developer. The concept is that we have web services that support XmlHttpRequest level 2 for cross-origin to allow clients to interact with these services. Lets see an example
AjaxStore – The Horrorscope Service
The horrorscope is a web service for giving a user its horoscope with a horror twist. Let’s see an example of an open service.
This PHP code is just an example of a CORS services that allow all origins
<?
$origin = $_SERVER['HTTP_ORIGIN'];
header('Access-Control-Allow-Origin: ".$origin);
header('Access-Control-Allow-credentials: true');
echo getUserHorrorscope();
?>
and let’s see the client side code:
var xhr = new XMLHttpRequest();
xhr.onload = function(e){
alert(xhr.responseText);
};
xhr.onerror = function(e){
alert("something bad happend, but not to you...");
};
xhr.open("GET",http://ajaxstore.amirharel.com/horrorscope.php?sign=gemini",true);
xhr.send(null);
You can try it yourself by sending an ajax request to : http://amirharel.com/labs/ajaxstore/hscope.php
Now let’s say you have a service that predicts the lottery numbers and you only want to allow it to payed customers, then you could just check the origin with a white-list to authorize it.
Summary
The CORS is a powerful tool and should be used to preform tasks that your server doesn’t add any value to you more then just a bridge to the outer world. In general, HTML5 features (WebWorkers, WevSockets…) are providing more tools for the front end engineers to shift more logic from the server to the client side and to build powerful applications that uses more the users resources and less the application servers.
I can’t wait to see what kind of AjaxStores will pop-up in the near future.








