Skip to content

Cross-domain resource sharing (CORS)

About 1730 wordsAbout 6 min

http

2020-08-29

Cross-domain resource sharing (CORS) is a mechanism based on HTTP Header. This mechanism allows the server to have permission to access resources on the loading server by allowing the server to indicate in addition to its own origin (domain, protocol, and port).

Cross-domain resource sharing Through the preflight request mechanism, check whether the server allows the real request to be sent. The browser sends a cross-domain resource hosted to the server Preflight request, In the preflight request, the header sent by the browser is marked with the HTTP method and the header used by the real request.

Preface

For security reasons, the browser will restrict cross-domain resource requests initiated in the script. For example, XMLHttpRequest and Fetch API follow the Same-origin policy, and non-same-original resource requests are not allowed by default. Web applications using these APIs can only load requested HTTP resources from the same domain of the application. Unless the response message contains the correct CORS response header

Overview

Cross-domain resource sharing A new set of HTTP header fields is added, allowing the server to declare which source sites have permission to access which resources through the browser. At the same time, for HTTP request methods that may have side effects on server data, the browser must first initiate a preflight request using the OPTIONS method. This will obtain whether the server allows cross-domain requests. Only after the server confirms that the permission is allowed will the actual HTTP request be initiated.

An error occurs when a CORS request fails, but for security, in JavaScript code, it is impossible to get the specific problem. We can only get the specific errors that appear by viewing the browser's console.

To enable CORS, we need to configure the CORS-related HTTP header field.

HTTP response header field

In CORS, the HTTP response header field mainly has the following:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • Access-Control-Max-Age
  • Access-Control-Expose-Headers
  • Access-Control-Allow-Credentials

Access-Control-Allow-Origin

Access-Control-Allow-Origin Response header field, used to specify the out-of-domain URI that allows access to the resource.

For requests that do not require carrying credentials, the server can specify that the value of the field be changed to a wildcard character (*), indicating that requests from all domains are allowed.

grammar:

Access-Control-Allow-Origin: <origin>
Access-Control-Allow-Origin: *

If the server specifies a specific domain name instead of *, the value of the Vary field in the response header must contain Origin. Used to tell the client that the server returns different content to different source sites.

Note

When responding to a request with credentials, the server must clarify the value of Access-Control-Allow-Origin, and cannot use the wildcard "*".

Example 1:

Allow access to all domains

Access-Control-Allow-Origin: *

Example 2:

Allow requests from https://pengzhanbo.cn

Access-Control-Allow-Origin: https://pengzhanbo.cn
Vary: Origin

Access-Control-Allow-Methods

Access-Control-Allow-Methods The response header field is used to preflight the response of the request. Specifies the HTTP method or method list that is allowed to be used by the actual request.

grammar:

Access-Control-Allow-Methods: <method>[, <method>]*

Example:

Access-Control-Allow-Methods: POST, GET, OPTIONS

Access-Control-Allow-Headers

Access-Control-Allow-Headers The response header field is used to preflight the response of the request. Specifies the header field allowed in the actual request.

grammar:

Access-Control-Allow-Headers: <header-name>[, header-name]*
Access-Control-Allow-Headers: *

The following specific headers are always allowed without having to declare them specifically:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type, but only one of the MIME types application/x-www-form-urlencoded,multipart/form-data,text/pain.

Example 1:

Custom request header. In addition to the request headers listed in the CORS security manifest, custom request headers are supported.

Access-Control-Allow-Headers: X-Custom-Header

Example 2:

Multiple custom request headers.

Access-Control-Allow-Headers: X-Custom-Header, X-My-Header

Access-Control-Max-Age

Access-Control-Max-Age The response header field indicates how long the return result of the preflight request can be cached**.

The return result refers to the information provided by: Access-Control-Allow-Methods and Access-Control-Allow-Headers.

grammar:

Access-Control-Max-Age: <delta-seconds>

delta-seconds indicates the maximum time (seconds) that the return result can be cached. In Firefox, the upper limit is **24 hours (86400 seconds). In Chromium, the upper limit is 2 hours (7200 seconds), and Chromium also stipulates that the default value is 5 seconds. If the value is **-1**, it means that caching is disabled, and OPTIONS preflight requests are required before each request.

**Example: **

Cache preflight requests for 10 minutes:

Access-Control-Max-Age: 600

Access-Control-Expose-Headers

Access-Control-Expose-Headers Response header field, listing which headers can be exposed to the outside as part of the response.

During cross-origin access, the getResponseHeader() method of the XMLHttpRequest object can only get some of the most basic response headers by default.

By default, there are only seven simple response headers that can be exposed to the outside:

  • Cache-Control
  • Content-Language
  • Content-Length
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

If you want the client to access other header information, you can list them.

grammar:

Access-Control-Expose-Headers: <header-name>[, <header-name>]*

**Example: **

Expose a non-simple response header:

Access-Control-Expose-Headers: X-My-Header

Expose multiple non-simple response headers:

Access-Control-Expose-Headers: X-My-Header, X-Custom-Header

Access-Control-Allow-Credentials

Access-Control-Allow-Credentials Response header field is used when requesting to include Credentials, Tell the browser whether it is possible to expose the response to the request to the front-end JavaScript code.

When the requested Credentials mode (Request.credentials) is include, the browser will be exposed to the front-end JavaScript code when the value of Access-Control-Allow-Credentials** is true.

Credentials can be cookies, authorization headers, or TLS client certificates.

grammar:

Access-Control-Allow-Credentials: true

Access-Control-Allow-Credentials Need to be with XMLHttpRequest.withCredentials Or use the credentials option in the Request() constructor of the Fetch API. Credentials must be configured on both the front and back ends for CORS requests with credentials to succeed.

**Example: **

Allow credentials

Access-Control-Allow-Credentials: true

Using XHR with credentials:

const xhr = new XMLHttpRequest()
xhr.open('GET', 'https://pengzhanbo.cn', true)
xhr.withCredentials = true
xhr.send(null)

Use Fetch with credentials:

fetch('https://pengzhanbo.cn', {
  credentials: 'include',
})

HTTP request header field

In CORS, the header field that can be used to initiate cross-domain requests is as follows:

  • Origin
  • Access-Control-Request-Method
  • Access-Control-Request-Headers

These header fields do not need to be set manually.

When developers use XMLHttpRequest to initiate cross-domain requests, they are already set up.

Origin

Origin The request header field indicates the source site for the preflight request or actual request.

grammar:

Origin: <origin>

The value of the origin parameter is the URI of the source site. It does not contain any path information, only represents the server name.

Access-Control-Request-Method

Access-Control-Request-Method The request header field is used for preflight requests. The function is to tell the server the HTTP method used in the actual situation.

grammar:

Access-Control-Request-Method: <method>

Access-Control-Request-Headers

Access-Control-Request-Headers The request header field is used for preflight requests. The function is to tell the server the header field carried by the actual request.

grammar:

Access-Control-Request-Headers: <header-name>[, <header-name>]*

Pre-flight request

A CORS preflight request is used to check that the server uses CORS, that is, cross-domain resource sharing.

Preflight Request Send an OPTIONS request through Send an OPTIONS request, and the request header contains the following fields:

  • Access-Control-Request-Method
  • Access-Control-Request-Headers
  • Origin

The browser will automatically issue a preflight request when necessary.

So under normal circumstances, front-end developers do not need to send such requests themselves.

Preflight requests and credentials

The CORS preflight request cannot contain credentials. The response to the preflight request must specify Access-Control-Allow-Credentials: true to indicate that the credentials can be carried for the actual request.

Simple Request

In some cases, CORS preflight requests are not triggered, and such requests can be expressed as simple requests.

If the request meets all the following conditions, it can be considered a simple request:

  • Using GET, HEAD POST request method
  • In addition to the header fields (Connection, User-Agent, etc.) that are automatically set by the user agent, and other headers defined in the Fetch specification as disable header name, Fields that are allowed to be set artificially are CORS-safety collection of header fields defined by the Fetch specification
  • No XMLHttpRequest object in the request has registered any listening events. The XMLHttpRequest object can be accessed using the XMLHttpRequest.upload property.
  • The ReadableStream object is not used in the request.

Assigned identity requests and wildcards

In response to a request with credentials:

  • The server cannot set the value of Access-Control-Allow-Origin to the wildcard *, but should set it to a specific domain, such as: Access-Control-Allow-Origin: <https://pengzhanbo.cn. >

  • The server cannot set the value of Access-Control-Allow-Headers to the wildcard *, but should set it to a list of header names, such as: Access-Control-Allow-Headers: X-Custom-Header, Content-Type

  • The server cannot set the value of Access-Control-Allow-Methods to the wildcard *, but should set it to a list of specific request method names, such as: Access-Control-Allow-Methods: POST, GET

Scenarios that require CORS

  1. HTTP request initiated using XMLHttpRequest
  2. HTTP request initiated using Fetch API
  3. Web fonts, cross-domain font resources used by CSS through @font-face
  4. WebGL map
  5. Use drawImage to draw the Images/video screen to canvas
  6. CSS graphics from images

Safety

In actual usage scenarios, use as little as possible wildcard * to allow access to all domains, or to allow all custom header fields. This may be risky in web security.