Cross-origin Resource Sharing is a mechanism that uses additional HTTP headers to tell browsers that a Web application can make cross-domain Resource requests.

Request type

A simple request

A request is considered a “simple request” if all of the following conditions are met:

  • The method used is
    • GET
    • HEAD
    • POST
  • The manually set header field can only be (note: it can also be setForbidden header nameIn, as inConnectionAccept-EncodingEtc, but the setting is invalid)
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type(The value range also meets the following requirements)
    • `DPR`
    • `Downlink`
    • `Save-Data`
    • `Viewpoer-Width`
    • `Width`
  • Content-TypeCan only be
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain
  • No event listeners are registered on any `XMLHttpRequestUpload` object used in the request; these are accessed using the
    XMLHttpRequest.upload property.
  • No
    ReadableStream object is used in the request.

Preview the request

The CORS precheck request occurs before the actual request and is used to check whether the server supports CORS to determine whether the actual request is safe to send. The precheck request uses OPTIONS.

When a request is not a “simple request”, a precheck request should be sent first, such as:

  • The way this request is requested is notGET,HEAD,POST
  • Alternatively, the request sets a custom header field, such asX-xxx
  • Or this requestContent-TypeValue is notapplication/x-www-form-urlencodedmultipart/form-data,text/plain, etc.

Cross-domain request procedures

For cross-domain requests, CORS requires the server to set a number of header fields, the most important of which is access-Control-Allow-Origin. As an example, the front-end uses AXIOS for HTTP transmission, and the back-end uses KOA as the server framework, and uses THE CORS middleware KOA2-CORS.

Simple cross-domain requests

// Client http://localhost:8080
simpleRequest() {
  axios({
    method: 'GET'.url: 'http://localhost:3000/api/simple'
  }).then(data= > {
    console.log(data);
  });
}
Copy the code
// Server http://localhost:3000
app.use(cors());
router.get('/api/simple', ctx => {
  ctx.body = { result: 'simple request success' };
});
Copy the code

The HTTP message:

The HTTP request header has an Origin field that indicates where the request came from. Access-control-allow-origin in the HTTP response header indicates which domain can Access the resource. Using Origin and access-Control-allow-Origin does the simplest Access Control.

Precheck request & formal request

// Client http://localhost:8080
mainRequest() {
  axios({
    method: 'POST'.url: 'http://localhost:3000/api/mainRequest'.headers: { 'X-test': 'CORS' } // Add a custom header field to trigger the precheck request
  }).then(data= > {
    console.log(data);
  });
}
Copy the code
// Server http://localhost:3000
app.use(cors());
router.post('/api/mainRequest', ctx => {
  ctx.body = { result: 'main request success' };
});
Copy the code

Precheck request message:

The access-Control-request-method field tells the server that the actual Request will use the POST Method. The access-Control-request-HEADERS Headers field tells the server that the actual Request will carry a custom Request header field, X-test. The server then decides whether the actual request is allowed.

The response header field access-Control-allow-methods indicates which Methods the server allows the client to initiate a request. Access-control-allow-headers indicates that the server allows the x-test field to be carried in the request.

Actual requested message:

The actual request sent the X-test header field with the response status code 200 OK.

As you can see, the Client and Server in the precheck request use more header fields for access control. So what are the CORS related request header fields and response header fields?

Header fields

HTTP request header field

  • Origin

    OriginThe header field represents the source of the precheck request or the actual request.
  • Access-Control-Request-Method

    Access-Control-Request-MethodThe header field is used forPreview the request. It tells the server the HTTP method used for the actual request.
  • Access-Control-Request-Headers

    Access-Control-Request-HeadersThe header field is used forPreview the request. This tells the server the header field carried by the actual request.

Note that the above request header fields do not need to be set manually; they are already set when a cross-domain request is made using the XMLHttpRequest object.

HTTP response header field

  • Access-control-allow-origin has the following syntax:

    Access-Control-Allow-Origin: <origin> | *  
    Copy the code

    The value of the Origin parameter specifies the outdomain URI that is allowed to access the resource. If the value of this field is wildcard *, requests from all domains are allowed. Note that if the server specifies a specific domain name rather than *, the value of the Vary field in the response header must contain Origin. This tells the client that the server returns different content for different source sites.

  • Access-control-allow-methods The access-Control-allow-methods header field is used to precheck the response to the request. This specifies the HTTP methods allowed for the actual request.

  • Access-control-allow-headers The access-control-allow-headers header field is used to pre-check the response to the request. This specifies the header field that is allowed in the actual request.

  • In an Access-Control-expose-headers cross-domain request, the browser by default only gets the following response header fields from the API:

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

    If you want to Access other response header information, you need to set access-Control-allow-headers on the server side. Access-control-expose-headers lets the server whitelist header fields that are accessible to the browser, such as:

    Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
    Copy the code

    This gives the browser access to the X-my-custom-header and x-another – custom-header response headers.

  • The access-control-max-age access-control-max-age field specifies how long, in seconds, the result of a precheck request can be cached, for example:

    Access-Control-Max-Age: 5
    Copy the code

    Indicates that after the first precheck request is sent, the interface will directly send the actual request if it accesses the interface within 5s. After 5s, the system will ask to send the precheck request first, and so on.

    app.use(
      cors({
        maxAge: 5}));Copy the code

    5s cache is set on the server. The actual request is as follows:

    Note that if you set the cache and still send the OPTIONS request every time, please check whether you have “disable cache” checked.

  • Access – Control – Allow – Credentials XMLHttpRequest. WithCredentials (or Request. Credentials) cross-domain Request, Whether the user agent should send credentials such as cookies, Authorization Headers or TLS Client certificates. Access-control-allow-credentials are used to: When the credentials are “true” (XHR and Fetch are set differently), access-Control-allow-credentials tells the browser whether to expose the response content to the front-end JS code. Such as:

    // Client http://localhost:8080
    simpleRequest() {
      axios({
        method: 'GET'.url: 'http://localhost:3000/api/simple'.withCredentials: true // Added the withCredentials option
      }).then(data= > {
        console.log(data);
      });
    }  
    
    // Server http://localhost:3000
    app.use(
      cors({
        maxAge: 5.// credentials: true}));Copy the code

    When the credentials: true is not set on the server, you can see an error message on the client when making requests:

    When the server sets the credentials: true, the client does not report errors.

    When pre-checking a request, the access-Control-allow-credentials response header field indicates whether the Credentials can be used in the actual request.

For the use of CORS response header fields, it is recommended to look at the source code of KOA2-CORS middleware. The code is only a few dozen lines long and is extremely clear and easy to understand.


The relevant content of CORS is mentioned above, and understanding it can better help us solve the problems in daily joint investigation, such as: how to set the server side across domains, why OPTIONS request appears when axios.post method sends an object, how can proxy server forward cookies and so on.