It might be a new concept to you, but CORS or Cross-Origin Resource Sharing is an important way for a restricted resource on a specific web page to get requested from a website which sits on a different domain.
While websites can easily embed (request) assets such as CSS, images and videos and scripts from a different origin (cross-origin), there are restrictions on other requests. For example, cross-domain requests referring to Ajax is generally blocked because sites usually apply a security policy that limits requests to same-origin requests. Cross-origin requests will be barred by default.
CORS is a way for servers and browsers to determine whether accessing resources cross-origin is safe. Because apps can determine whether cross-origin access is safe it means that developers have more freedom to implement website functionality – compared to a situation where they are restricted to requests that are same-origin. CORS aims to be more secure than a simple cross-origin request that is not subject to any limits or restrictions.
The Fetch Living Standard, specified by WHATWG, contains the CORS specification and explains how a CORS implementation should work. CORS was also included in an earlier Recommendation from the W3C.
Understanding the functionality of CORS
In essence, by describing a new type of HTTP header, CORS enables a browser to request a URL that is remote – assuming it has permission to do so. Validation and authorization can be performed server-side to some degree, but usually the browser will take the role of supporting CORS headers and adhering to any specified restrictions.
Where a request can modify data (whether it is an HTTP or an Ajax request) the CORS specification will ask that the browser applies a “preflight”. This means that the browser will ask for supported methods from the server using the HTTP OPTIONS method. Once these “arrive” the actual request will be sent using the usual HTTP method. A server has the option to advise the client that credentials such as HTTP authentication information or a cookie is sent to verify a request.
An example of CORS in action
Let’s say someone wants to visit the website http://www.supersite.com, with the web page then trying to put in place a cross-origin HTTP request which gets data from http://help.supersite.com. If the user’s browser is supportive of CORS it will try to make a valid cross-origin HTTP request to help.supersite.com by doing the following:
- A GET request is sent by the browser, and the browser includes an extra “origin” HTTP header which is sent to help.supersite.com, this header contains the domain of the parent that sent the original request.
Origin: http://www.supersite.com
- The sever that gets the request over at help.supersite.com could respond with one of the following:
- The data that was requested from www.supersite.com alongside an ACAO header (that’s an access control allow origin header) which implies that it accepts requests from the origin, so this could look like:
Access-Control-Allow-Origin: http://www.supersite.com
- The data, alongside an ACAO header which says that it accepts a request from any domain, which looks like this:
Access-Control-Allow-Origin: *
- A page throwing up an error, stating that it does not accept cross-origin requests
- The data that was requested from www.supersite.com alongside an ACAO header (that’s an access control allow origin header) which implies that it accepts requests from the origin, so this could look like:
Sometimes an API response or a page is considered to be public content which can be accessed by anyone, and that’s where the wildcard response is used so that code on any site can access it. For example, take Google Fonts and freely available web fonts that are hosted on this service for the public.
The object-capability model is another place where wildcard origin policies are used because the pages have URLs that simply cannot be guessed – and the idea is that any who knows the unique URL should be able to enjoy access.
There is a special value of “”. This means that requests cannot supply credentials – this prohibits the use of client-side SSL, HTTP authentication or even the use of cookies – none of these are allowed in the request that’s sent cross-domain.
CORS architecture states that the ACAO header must be set by an external service – it’s not set by the application server which sends the original request. For example, help.supersite.com would make use of CORS to permit a browser to send a request from www.supersite.com.
An example of CORS preflight
Modern CORS-supporting browsers will require an additional “preflight” request when some cross-domain Ajax resources are requested. This is done to determine whether the browser has the permission to take the action it wants to take. CORS preflights exist because of the implications on user data.
OPTIONS /
Host: help.supersite.com
Origin: http://www.supersite.com
Let’s say then that help.supersite.com is happy to take the requested action it could send back these HTTP headers:
Access-Control-Allow-Origin: http://www.supersite.com
Access-Control-Allow-Methods: PUT, DELETE
The next step is for the browser to then make the request it originally wanted to make. On the flipside, if help.supersite.com does not allow cross-site HTTP requests it will simply send back an error when the OPTIONS request is sent – as a consequence, the browser won’t make the requests it originally intended to make.
Headers specific to CORS
The HTTP headers used by CORS include
Request Headers
- Origin
- Access-Control-Request-Method
- Access-Control-Request-Headers
Response headers
- Access-Control-Allow-Origin
- Access-Control-Allow-Credentials
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
Which browsers support CORS?
Given that CORS is a relatively new technology that is dependent on browser support it’s worth noting that you need an up to date browser to use a website that makes use of CORS. For example, Chrome 28+ will work, and so will Opera 15+ and Android 4.4+. Some Presto-enabled browsers – that’s Opera – will work, while Geck from 1.9.1 onwards works. Every version of Microsoft Edge also supports CORS.
The history of CORS
Three staff members at Tellme Networks, Michael Bodell, Matt Oshry and Brad Porter originally started working on CORS in March 2004 as they intended that it should be included in VoiceXML version 2.1. The idea was to make sure that VoiceXML browsers can safely make data requests that are cross-origin.
However, the mechanism that they developed clearly had wider applications beyond VoiceXML and that’s why CORS was subsequently added to an implementation NOTE. W3C’s web apps working group, alongside major browser developers, started formalising the specification into a working draft – which was eventually put on track to be formally recommended by W3C.
The first W3C working draft was submitted in May 2006 and nearly three years later the draft was given it’s name – CORS. It was only in the beginning of 2014 that CORS was formally accepted as a recommendation by the W3C.
Differences between JSONP and CORS
It’s worth noting that CORS can be seen as a better and more contemporary solution compared to JSNOP patterns. CORS offers a number of advantages which include the fact that it supports a range of HTTP requests – it’s not restricted to GET, like JSONP.
Furthermore XMLHttpRequest can be used in the context of CORS and this means that CORS can handle errors better than JSONP. It’s also worth noting that JSONP is susceptible to cross-site scripting problems (XSS) where the external website is hacked, in contrast CORS enables a site to parse responses manually which in turn improves overall security.
However, JSONP does have the advantage that it is better supported by legacy browser where CORS is not yet supported, but it is of little consequence today because CORS is now widely supported by everyday browsers.
No comment yet, add your voice below!