Create your own AjaxStore with XMLHttpRequest Level 2

January 23, 2011

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&param2=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.

Bookmark and Share
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • FriendFeed
  • LinkedIn
  • StumbleUpon
  • Twitter

tags: , ,
posted in Blog by Amir Harel

 
Powered by Wordpress and MySQL. Theme by openark.org