5 minutes with – Cross-Origin Resource Sharing (CORS)

To improve the user experience on the web 2.0, Javascript is largely used in the web page. They are put in pages and in specific libraries so, they are called in the same domain and, even, cross domain.

Specially for that last point, I’d like to illustrate the way to access extra domain resources by adding a specific heade

CORS (Cross-Origin Resource Sharing) is a specific realesed by W3C (http://www.w3.org/TR/cors/) that allows to access a resource from a different domain.  As you well know, calling from domain wordpress.com to wordpress.com doesn’t give you any problem. The real problem is calling from wordpress.com to myblog.com. In that last case, you get something like “Access denied”.

Cors’s the solution of this issue. In the following sequence chart is illustrated the way how it works.

Cross-Origin Resource Sharing (CORS)

Everything fine? The resource “hi.js” is normally served ’cause is in the same domain. The resource “goodbye.js” is served used Cors technology. Let’s see how it works.

First some code (I took it from http://www.html5rocks.com/en/tutorials/cors/)

// Create the XHR object.
function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();                    
  if ("withCredentials" in xhr) {
    // XHR for Chrome/Firefox/Opera/Safari.
    xhr.open(method, url, true);
  } else if (typeof XDomainRequest != "undefined") {
    // XDomainRequest for IE.
    xhr = new XDomainRequest();
    xhr.open(method, url);
  } else {
    // CORS not supported.
    xhr = null;
  }
  return xhr;
}

// Make the actual CORS request.
function makeCorsRequest() {
  // All HTML5 Rocks properties support CORS.
  var url = 'http://localhost./getcookie.html?rnd='
            + Math.floor(1000000*Math.random());

  var xhr = createCORSRequest('GET', url);
  if (!xhr) {
    alert('CORS not supported');
    return;
  }

  // Response handlers.
  xhr.onload = function() {
    var responseText = xhr.responseText;
    alert(responseText);   
  };

  xhr.onerror = function() {
    alert('Woops, there was an error making the request.');
  };
  xhr.send();
}

I get the resource from my localhost because was easier for me configuring my local apache.

Put this code into a web page and the call it. I opened Fiddler before making the request and the result has been the following:

GET http://localhost./getcookie.html?rnd=267768 HTTP/1.1
Accept: */*
Origin: http://forum.wordpress.it
Accept-Language: it
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 ...
Host: localhost.
Proxy-Connection: Keep-Alive
Pragma: no-cache

Take a look at “Origin” parameter. This will be used to check the caller origin on server side.

I used Apache Web Server on my localhost, you can use your prefer web server configuring it according with this tutorial http://enable-cors.org/server.html.

My apache’s configuration is the following

LoadModule headers_module modules/mod_headers.so
...
LoadModule rewrite_module modules/mod_rewrite.so
...
<IfModule headers_module>
  Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
  SetEnvIf Origin "http(s)?://(forum\.wordpress\.it|forum2013-wordpress\.devsvil\.dev)$" AccessControlAllowOrigin=$0
  Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
</IfModule>

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{ENV:AccessControlAllowOrigin} !(http://forum\.wordpress\.it|http://forum2013-wordpress\.devsvil\.dev)$ [NC]
  RewriteRule getcookie\.html$ empty\.html [NC,R=301,L]
</IfModule>

I enable the headers and rewrite modules to avoid access at not allowed resources from not valid Origin source.

HTTP/1.1 200 OK
Date: Mon, 30 Sep 2013 12:58:32 GMT
Server: Apache/2.2.14 (Win32)
Last-Modified: Thu, 26 Sep 2013 15:28:31 GMT
ETag: "170000000a656f-34-4e74b05c177c5"
Accept-Ranges: bytes
Content-Length: 52
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: http://forum.wordpress.it
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

The Apache server’s response includes the headers “Access-Control-Allow-Methods” and “Access-Control-Allow-Origin” according with my server configuration.

At this stage, the question is “does it work with jQuery ?”. The answer is, obviously yes but with some limitation at some old browser like IE8. Take a look at http://bugs.jquery.com/ticket/8283 to get the problem explanantion.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s