Using CORS instead of JSONP to make cross site requests

Introduction to CORS

CORS (Cross Origin Resource Sharing) is a mechanism specifies by W3C (draft), for allowing browsers to make cross origin requests for resources on other domains under certain conditions. It’s related to JSONP because it solves a similar problem, namely loading data from one domain, into a web application running on a different domain. A difference is that CORS supports the full palette of HTTP verbs, not just GET.

See also: http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing

OK, say you have two domains, example.com and skipperkongen.dk. A web application on http://example.com, wants to fetch data from the resource http://skipperkongen.dk/getdata.php, using an AJAX request. Normally this is not possible due to the same origin policy.

In a browser with CORS support this is possible, e.g. the latest Firefox and Chrome browsers.

Server requirements and client requirements

CORS is possible under the following conditions:

  • The server adds a special response header: Access-Control-Allow-Origin: *
  • The client (browser) has support for CORS

If both these conditions are met, the AJAX request goes through. You can use an actual domain-name in place of the “*” wildcard.

Enable CORS for your service

How do you enable CORS for your web service? There is a page for this (examples for PHP, CGI, .NET etc):

http://enable-cors.org/

Example

Here is an example

A javascript web application on http://example.com executes the following AJAX code to fetch some data from http://skipperkongen.dk/getdata.php, hoping that the browser won’t block the request due to the same origin policy:

Javascript:

var client = new XMLHttpRequest();
client.open("GET", "http://skipperkongen.dk/getdata.php")
client.onreadystatechange=function()
  {
  if (client.readyState==4 && client.status==200)
    {
      alert(client.responseText);
    }
  }
client.send()

This is the HTTP exchange that takes place.

GET request, example.com –> skipperkongen.dk:

GET /getdata.php HTTP/1.1
Host: skipperkongen.dk
Connection: keep-alive
Origin: http://example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1
Accept: */*
Referer: http://example.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

GET response, example.com <-- skipperkongen.dk:

HTTP/1.1 200 OK
Date: Wed, 19 Oct 2011 13:31:15 GMT
Server: Apache/2.2.20 (Unix) DAV/2
Content-Length: 16
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
Access-Control-Allow-Origin: example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 86400
 
Hello example.com

A message “Hello example.com” appears in an alert box. Why did this work? If you look in the response from skipperkongen.dk, you’ll notice the following response header was set:

Access-Control-Allow-Origin: example.com

If the browser has support for CORS, and the web application is running on example.com, the browser will allow the web application to use the data fetched from skipperkongen.dk. Otherwise the request is blocked.

Demo

You can try a demo of CORS, if you have a browser with CORS support (e.g. the latest Firefox or Chrome browser):

http://saltybeagle.com/cors/

This demo fetches data from the page at (which returns CORS headers):

Leave a Reply