CORS: HTML5 approach to crossdomain policies

Traditionally web browsers restrict loading content to the same origin server. This means that you can’t load content from another domain different than your own. There’s been several ways to solve this problem and HTML5 introduces a new one.

Current support

JS

JS developers have used a workaround consisting in using JSONP (JSON with Padding). Since the same domain restriction don’t apply to dynamically loaded Javascript code, JSONP solves the crossdoamin issue by wrapping the JSON response in a JS function call. This approach assumes the server is ready to deliver JSONP data. JSONP is quite common and jQuery supports it natively.

Flash

This crossdomain policy behavior is well known in Flash as well and developers have been getting around this restricction (also imposed in the Flash player) with the –now famous– crossdomain.xml policy file.

All these approaches require the foreign server to implement a solution on their end (host the crossdomain file or implement JSONP).

HTML5

One of html5 new features allows for a different workaround to crossdomain restrictions that doesn’t involve changing the format of the response but rather the header of it. This means that we can get away without JSONP and utilize JSON or any other format prefered by our app.

CORS

This new feature is called CORS (Cross Origin Resource Sharing) and its intended to prevent crossdomain scripting attacks while still enabling sites to load content from external servers.

It works in two simple steps:

STEP 1: HTTP Request

Besides setting who the host of our request is (http://api.foo.com) we also set who the requester is:

Origin: http://api.origin.com

This Origin header is set by the browser and can’t be controlled by the user, and it’s send along with the full HTTP Request header:

GET /cors HTTP/1.1
Origin: http://api.origin.com
Host: api.foo.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: ...

STEP 2: HTTP Response

If the server accepts crossdomain requests its response will include (besides the requested content) who the response is intended for (http://api.origin.com). All the new HTML5 headers for CORS are prefixed with “Access-Control-”.

Access-Control-Allow-Origin: http://api.origin.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8

SUPPORT

CORS is an HTML5 feature and, therefore, it’s not yet fully implemented across all browsers. Particularly, it’s not supported yet on Opera (desktop or mobile) and supported only partially in IE8 and 9 (using the XDomainRequest object but with some crazy restrictions).

The good news is that jQuery already implements CORS requests (jQuery.support.cors) natively for all browsers that can support it. Additionally there are some plugins in development for IE8 and IE9.

You can check the full support for CORS for more details.

CONCLUSION

Leaving Opera aside and old versions of IE (6 and 7), CORS are pretty well supported and can be reliably used. If you own the infrastructure you can more easily get over the biggest hurdle which is implementing Access-Control headers on the external server (although this will become more and more common, it still isn’t).

Because CORS eliminates the need for JSONP, code can be simpliffied and different response formats can be used again: plain HTML, XML, JSON, etc.

RESOURCES

You can read the w3c definition of CORS or the more readable tutorial at HTML5Rocks.

  • My name is Omar Rodriguez-Rodriguez. I'm a creative, a technologist, a coder, a traveler, and an art fanatic.

    Omar Rodriguez-Rodriguez — omarrr

  • Categories