CORS in brief

Q: What is CORS?

A: CORS or Cross-Origin Resource Sharing, is a mechanism and set of specifications developed by W3C as part of HTML5 specifications for organizing access to online resources in one online target domain by another domain (usually through AJAX and RESTful APIs).

Q: What was there before CORS?

A: Before CORS, same-origin policy was applied to prevent cross-site scripting security issues, which means that calling certain resources (i.e. fonts, JavaScript and XMLHttpRequest) from another domain was forbidden.

Q: Does CORS allow unrestricted access to online shared resources?

A: No, the target domain holding the shared resource or script must instruct a web browser that it “allows” certain request types for this resource from certain requesting domains.

Q: Is CORS similar to authentication?

A: No, authentication is checked by the web server before replying with a Response, while CORS is checked by a web browser that supports CORS before sending a Request (in some cases) or after sending the Request but before rendering a Response (in other cases). If the Request from the originator domain was not allowed, the browser generates an exception and prevents rendering or executing the requested resource.

Q: Which web browsers support CORS?

A: CORS is supported in the following browsers:

  • Chrome 3+
  • Firefox 3.5+
  • Opera 12+
  • Safari 4+
  • Internet Explorer 8+

(a complete list of supported browsers at http://caniuse.com/#search=cors)

Q: Are there other non-browser clients supporting CORS?

A: CORS is allowed and checked by web browsers, while other clients like applications (e.g. Wfetch.exe) and browser extensions (e.g. POSTMAN or RESTClient) does not go through CORS checking and hence access is unrestricted. This also includes requesting remote resources from within server-side scripting languages like ASP.NET because the request is generated from the host engine (i.e. IIS) and not the browser.

Q: How to enable CORS on a web server?

A: A web server allows CORS by replying with a Response containing one (or a combination) of the headers below, depending on the case:

  • Access-Control-Allow-Origin: *
    Allows all domains to request shared resources, or replace * with a a comma separated list of domains allowed.
  • Access-Control-Allow-Methods: *
    Allows all web methods, or replace * with a comma separated list of methods allowed (e.g. GET, POST, OPTIONS).
  • Access-Control-Allow-Headers: *
    Allows all standard and custom request headers, or replace * with a comma separated list of allowed request headers.
  • Access-Control-Allow-Credentials: true
    Allows sending cookies credentials with requests (when withCredentials property of XMLHttpRequest is true).

All the above headers are set either in server configurations (e.g. httpd.conf for Apache, or web.config for IIS) or in server-side code of web methods like in PHP, JSP, or ASP.NET via method attributes.

Q: How to enable CORS on a browser?

A: You cannot. CORS is enabled only from the server, while a browser (assuming a CORS-supported browser) just follows server headers instructions.

Q: How CORS enabled browsers treat CORS requests?

A: For all CORS requests, the browser adds Origin header to the Request, informing the target server of its origin.

If the Request is simple, the browser will check the header values of the target server Response and then either render it or raise an error if the Request was not allowed by the target server.

If the Request is not simple, the browser will add additional headers to the Request, like:

  • Access-Control-Request-Method:
    Specifying the intended HTTP method of the Request (GET, POST, PUT, DELETE, etc.)
  • Access-Control-Request-Headers:
    A comma separated list of the intended HTTP headers that are ready to be sent to the target server if allowed.

Q: When a Request is considered simple?

A: A Request is simple when its method, headers, and content type are all simple, namely:

  • Simple HTTP methods: HEAD, GET, POST
  • Simple headers: Accept, Accept-Language, Content-Language, Last-Event-Id, Content-Type
  • Simple Content-Types: text/plain, multipart/form-data, application/x-www-form-urlencoded

Any Request that does not meet all the criteria above are not considered simple.

Q: What happens for non-simple Requests?

A: Web browsers should send a preflight Request first before the actual Request is sent to the target server in case of non-simple Requests. This preflight Request is like asking for server permission, and it is in a form of a call using the HTTP method OPTINS, containing in headers both the intended method of the actual call and the intended headers to be sent in the actual call if the target server Responded that all  are allowed.

Target server Responds with the allowed methods, headers, and content-types. If allowed values matches those of the actual Request, the browser then sends it.

cors
source: http://crazygui.files.wordpress.com/2012/08/cors.png

Update:

Forgot to mention that the public end-point http://headers.jsontest.com/ is a CORS enabled server that echoes back the headers sent by web browser, so you can check what headers are you sending. Read more about JSON Test

References