Table of Contents

About

Cross-origin resource sharing (CORS) 1) is a mechanism that:

In short, a HTTP server may allow or not to receive cross-origin requests with or without credentials (ie cookie)

When

This mechanism is used during a browser fetch and:

CORS does not apply to media resources

Motivation / Goal

The main motivation behind Cross-Origin Resource Sharing (CORS) is:

Browser vs other Application

This is the browser's responsibility (ie user-agent) to enforce this policy.

A native application (ie not running in the browser) may not bother applying them.

Example / Getting started / Explanation

The article just below explains the basic about the what and the how of CORS. If this is the first time that you encounter a CORS issue, this is a good reading point to start:

Type

Cross-origin HTTP requests are divided into two types:

  • simple requests 2)
  • and non-simple requests.

Simple

An HTTP request is simple if all of the following conditions are true:

Simple request does not need the extra authorization request known as preflight or option request.

Non-simple

All cross-origin HTTP requests that are not simple are non-simple requests.

For non-simple request, an extra authorization request known as preflight or options is executed.

Policy

The CORS fetch procedure policy is on a simple level:

Below is the complete CORS fetch procedure policy as described by the specification 4)

Cors Flowchart

Preflight request

The Preflight request is an extra authorization request that is executed if the request is not simple.

A Preflight request is a request:

The browser checks the headers and upon browser “approval”, the browser sends the actual request with the actual HTTP request method (ie make available to the javascript)

The preflight response may be cached via the access-control-max-age response header

CORS Response Headers

The server sends a response with headers (in all cross request - preflight or not) indicating what is allowed. See Response headers

For instance, the most important is the access-control-allow-origin header that indicates which origin sites are allowed.

For example, if you add the below header to your response, you will allow the page/script of http://www.example.com to make request in the browser against your website.

Access-Control-Allow-Origin: http://www.example.com

Enable

To enable CORS request, you need to set the appropriate response headers via the following possibilities:

Web Server

Each third application web server has its way to configure the setting of response header for a request.

Http server

If you are developing or using your own http server in your code, you would generally set the CORS Headers via a handler.

const allowCrossDomain = function (req, res, next) {
  res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type');

  next();
};
app.use(allowCrossDomain);

Proxy

A a gateway (reverse proxy) can be configured to add the cors headers to a response.

Proxy are just http server that acts as a middle-man where the http requests and response transit.

Headers

The HTTP headers that configure the CORS authorization are listed below 5)

Request headers

This is the headers that a preflight_request uses to check what is allowed or not in a cross-origin request.

Origin

The origin request header indicates the origin of the code that want to fetch a resource

Access-Control-Request-Method

Indicates which method a future CORS request to the same resource might use.

Access-Control-Request-Method: POST

Access-Control-Request-Headers

Indicates which headers a future CORS request to the same resource might use.

Response headers

If an URL resource implements CORS, the server needs to define the request property that it will accept (ie

  • origins
  • HTTP methods
  • and type of data

Access-Control-Allow-Origin

Access-Control-Allow-Origin (ACAO) define the allowed origins

  • Open to every origin
Access-Control-Allow-Origin: *  

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

Example of error that you can get:

Origin is not allowed by Access-Control-Allow-Origin No 'Access-Control-Allow-Origin' header is present on the requested resource.

Access-Control-Allow-Credentials

Indicates whether the response can be shared when request’s credentials mode is include.

access-control-allow-credentials: true

Access-Control-Expose-Headers

Give the permission to the code that makes the cross-origin rquest, to list the headers that were set (ie the code knows which header was set but cannot read their value)

Access-Control-Expose-Headers: Content-Type

To give the permission to read the value, see the header access-control-allow-headers

Access-Control-Max-Age

The preflight request is valid and goes into the preflight cache for how many seconds.

Example for 20 days:

Access-Control-Max-Age: 1728000;

Access-Control-Allow-Methods

Which methods are allowed in a cross-origin request

Access-Control-Allow-Methods: PUT, DELETE

Access-Control-Allow-Headers

This header is used in response to the preflight_request which includes the access-control-request-headers to indicate which HTTP headers are allowed by a cross-origin request.

Example

Access-Control-Allow-Headers: x-requested-with, Content-Type, origin, authorization, accept, client-security-token

Support

Response to preflight request doesn't pass access control check

A preflight request is Options request.

Response to preflight request doesn't pass access control check No 'Access-Control-Allow-Origin' header is present

Cors Error

Just add the Access-Control-Allow-Origin to the response. See enable cross request

The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'

Failed to load http://api.lavandiere.local/graphql.php: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://docker-host:78' is therefore not allowed access.

Cors Error Credential Mode Include

No luck

Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

Answer: Configure the server to set the header access-control-allow-headers

Example with apache

Header set Access-Control-Allow-Headers "Content-Type"

Documentation / Reference