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

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, the 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 the Site2 are not accessible to any other origin. The Access-Control-Allow-Origin header makes the 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 browsers that it is permitted to use an additional origin.

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:

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:

Non-simple requests

The request is "non-simple" when the network level is complex. Firstly, the browser sends a data-less "preflight" OPTIONS request for verifying that the server will accept the request. A request is considered non-simple when either or both use an HTTP verb such as PUT or DELETE.

Let's consider the following scenario:

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

OPTIONS /some_page HTTP/1.1
Origin: http://site1.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type
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 which preflight is successful is treated the same as a simple one.

The browsers send the 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 as same as in case of a simple request:

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