W3docs

How Does the Access-Control-Allow-Origin Header Work

Read this tutorial and learn about how the Access-Control-Allow-Origin response header works. Also, read about CORS, the origin, and non-simple requests.

The Access-Control-Allow-Origin response header indicates if the response can be shared with requesting code from the given origin or not.

Let's explain the process. For example, if Site1 is trying to fetch content from Site2, Site2 can send an Access-Control-Allow-Origin response header to inform the browser that the page's content is accessible to certain origins. By default, the pages of Site2 are not accessible to any other origin. The Access-Control-Allow-Origin header makes cross-origin access by specific requesting origins possible.

What is CORS?

CORS or Cross-Origin Resource Sharing is a mechanism that uses additional HTTP headers to instruct the browser that cross-origin requests are permitted.

What is origin?

The origin of web content is defined by the scheme (protocol), host (domain), and URL's port that is used to access it. Two objects can have the same origin if the scheme, host, and port match.

A response that instructs the browser to allow code from any origin to access a resource should include:

HTTP Response Header

Access-Control-Allow-Origin: *

A response that instructs the browser to allow requesting code from the origin https://w3docs.com to access a resource should include:

HTTP Response Header

Access-Control-Allow-Origin: https://w3docs.com

Note

When Access-Control-Allow-Credentials: true is used, the Access-Control-Allow-Origin header cannot be set to *. It must specify the exact requesting origin.

Non-simple requests

A request is considered "non-simple" when it triggers a preflight check. The browser sends a data-less "preflight" OPTIONS request to verify that the server will accept the actual request. A request is considered non-simple when it uses HTTP methods other than GET, HEAD, or POST; includes custom headers; or uses a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain.

Let's consider the following scenario:

Assuming that Site1 wants to send a PUT request, the browser would first send a preflight request:

HTTP Preflight Request

OPTIONS /some_page HTTP/1.1
Origin: http://site1.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
Danger

There is no need to add the Access-Control-Request-Method and Access-Control-Request-Headers manually because they are added by the browser automatically.

A non-simple request whose preflight is successful is treated the same as a simple one.

The browser sends the actual request:

HTTP Actual Request

PUT /some_page HTTP/1.1
Origin: http://site1.com
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }

The server sends back an Access-Control-Allow-Origin header the same as in the case of a simple request:

HTTP Response Header

Access-Control-Allow-Origin: http://site1.com