Are you familiar with the following scenario?

The interviewer; Have you encountered cross-domain problems and how did you solve them?

Job seeker: Generally, the backend is configured with CORS across domains

Interviewer: Can you tell me how to configure it in detail?

Job Seeker:…… I don’t know. It’s all backend configuration

The above scenario is vivid for me, Hai, because I am the candidate. As a front end to cross-domain and cross-domain related knowledge points are not familiar with in fact is very should not. Although CORS is usually configured by server-side students, it is necessary to be familiar with it. If you don’t know anything about it in the interview, it will undoubtedly make the interviewer doubt your learning attitude and skills.

A little too much nonsense, in short, as a front-end understanding of CORS is very necessary. I have studied a wave of CORS and made the following learning summary.

What is CORS?

Cross-source resource sharing (CORS) (or cross-domain resource sharing as it is collocially translated) is a mechanism that uses additional HTTP headers to tell browsers to allow Web applications running on one source to access selected resources located on a different source. When a Web application makes an HTTP request that is different from its own source (domain, protocol, or port), it makes a cross-source HTTP request. — MDN

In plain English, cross-domain requests are browser-restricted due to same-origin policy restrictions. But cross-domain requests are a common requirement, so browsers have developed CORS mechanisms. Relax restrictions by setting HTTP headers to control whether cross-domain requests can be made.

An example of a cross-source HTTP request: JavaScript code running on Domain-a.com uses XMLHttpRequest to initiate a request to domain-b.com/data.json.

The Cross-source domain resource sharing (CORS) mechanism allows Web application servers to control cross-source access to secure cross-source data transfer.

When should I use CORS?

  • Cross-domain Ajax and FETCH requests

  • Web fonts (CSS uses cross-source font resources via @font-face) (Note that CSS fonts and images are different, font files are cross-domain restricted)

  • WebGL map

  • Draw Images/video Images to canvas using drawImage

  • A The Download attribute of the tag

Functions overview

Cross-source resource sharing standards have added a new set of HTTP header fields that allow servers to declare which source sites have access to which resources through the browser. In addition, the specification requires that HTTP request methods (especially HTTP requests other than GET, or POST requests paired with certain MIME types) that may have adverse effects on server data, The browser must first issue a preflight request using the OPTIONS method to know if the server will allow the cross-source request. The actual HTTP request is made only after the server confirms that it is allowed. In the return of the precheck request, the server side can also inform the client whether it needs to carry identity credentials (including Cookies and HTTP authentication related data). — MDN

A simple request

Some requests do not trigger a CORS precheck request, which we call a simple request. A simple request needs to satisfy all of the following conditions

  • Use one of the following methods:

    • GET

    • HEAD

    • POST

  • Except for header fields that are automatically set by the User Agent (for example, Connection, user-agent) and other headers that are defined in the Fetch specification to disable header names, fields that are allowed to be set artificially are the set of CORS safe header fields defined by the Fetch specification. The set is:

    • Accept

    • Accept-Language

    • Content-Language

    • Content-type (Additional restrictions need to be noted)

    • DPR

    • Downlink

    • Save-Data

    • Viewport-Width

    • Width

  • The value of the content-type is limited to one of the following:

    • text/plain

    • multipart/form-data

    • application/x-www-form-urlencoded

  • No ReadableStream object is used in the request

  • None of the XMLHttpRequestUpload objects in the request have any event listeners registered; The XMLHttpRequestUpload object can be accessed using the xmlHttprequest.upload attribute

Example: A simple request

var invocation = new XMLHttpRequest();

var url = 'http://xxx.com/api/getname';

invocation.open('GET', url, true);

invocation.onreadystatechange = (state) = > {
    console.log(state)
};

invocation.send(); 
Copy the code

For simple requests, the server CORS configuration is simple

Access-control-allow-origin: http://xxx.com access-Control-allow-origin: http://xxx.comCopy the code

Non-simple request

We call requests that do not meet the criteria for simple requests non-simple requests.

Example: a non-simple request

var invocation = new XMLHttpRequest();

var url = 'http://xxx.com/api/getname';

invocation.open('GET', url, true);
// Set an insecure header, so it does not meet simple requests
invocation.setRequestHeader('X-PINGOTHER'.'pingpong');
invocation.setRequestHeader('X-FIEld'.'xxx');

invocation.onreadystatechange = (state) = > {
    console.log(state)
};

invocation.send(); 
Copy the code

For non-simple requests, precheck requests need to be sent first for security.

Preview the request

Precheck requests do not carry entity data, and the server cannot return redirects for precheck requests

The precheck request is a request with the OPTIONS method, which is mainly used to query the request method and header field accepted by the server

Access-Control-Request-Method: GET
Access-Control-Request-Headers: X-PINGOTHER, X-FIEld
Copy the code

Access-control-request-method tells the server that the actual Request will use the POST Method, Access-control-request-headers tells the server that the Request will carry the custom Request header fields x-Pingother and X-Field. The server then decides whether the actual request is allowed.

For prechecked requests, the server needs to set the following response header to indicate that the server will accept subsequent actual requests

Access-control-allow-origin: http://foo.example // Access-Control-allow-methods: POST, GET, OPTIONS // Access-Control-allow-headers: x-pingother, content-typeCopy the code

The precheck request has a validity period. For the same request, if the precheck request is not invalid, the same request does not need to be sent again

The actual request

After the precheck request is complete, if the server returns an acceptable request method, request domain name, and request header that match the actual request, the browser will initiate the actual request. The actual request is consistent with the normal request for the browser.

For the server, the actual request also needs to set the CORS acceptable domain

Access-control-allow-origin: http://xxx.com access-Control-allow-origin: http://xxx.comCopy the code

Attached identity certificate

For cross-domain requests (Ajax/FETCH), browsers do not automatically send requests and need to proactively set up to carry cookies

var invocation = new XMLHttpRequest();

var url = 'http://xxx.com/api/getname';

invocation.open('GET', url, true);
invocation.withCredentials = true;

invocation.onreadystatechange = (state) = > {
    console.log(state)
};

invocation.send(); 
Copy the code

The server needs to set the acceptable fields and accept cookies

Access-Control-Allow-Origin: http://xxx.com
Access-Control-Allow-Credentials: true
Copy the code

In the case of non-simple requests, the response headers of pre-check requests also need to carry access-Control-allow-credentials to carry cookies across domains

Related header fields

HTTP response header field

Set by the server (mostly configured on the server Nginx), is the main configuration to implement CORS

Access-Control-Allow-Origin

The server specifies an acceptable external domain, which can be a specific domain name or a wildcard domain name.

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

Note: Requests with credentials cannot be set to wildcards

Access-Control-Expose-Headers

In cross-source access, the getResponseHeader() method of the XMLHttpRequest object takes only the most basic response headers, Cache-control, Content-language, Content-Type, Expires, last-Modified, Pragma. To access other headers, the server needs to set this response header.

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

Access-Control-Max-Age

In response to a precheck request, set the validity period of the precheck request in seconds. The validity period cannot exceed the maximum validity period specified by the browser

Access-Control-Max-Age: <delta-seconds>
Copy the code

Access-Control-Allow-Credentials

In response to predetected or actual requests, set to allow cookies, default to false

Access-Control-Allow-Credentials: true
Copy the code

Access-Control-Allow-Methods

Responding to a pre-detected request indicates which HTTP methods are allowed in the actual request.

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

Access-Control-Allow-Headers

Respond to a predetected request, specifying the header field allowed in the actual request.

Access-Control-Allow-Headers: <field-name>[, <field-name>]*
Copy the code

HTTP request header field

The request header field of CORS is carried proactively by the browser and does not need to be manually set by the developer. This is also the reason why the front end is not familiar with CORS.

Origin

The Origin header field indicates the source of the precheck request or the actual request.

Origin: <origin>
Copy the code

Note that the Origin header field is always sent in all Access Control requests.

Access-Control-Request-Method

Used to precheck requests. It tells the server the HTTP method used for the actual request.

Access-Control-Request-Method: <method>
Copy the code

Access-Control-Request-Headers

Used to precheck requests. This tells the server the header field carried by the actual request.

Access-Control-Request-Headers: <field-name>[, <field-name>]*
Copy the code

reference

  • Cross-source Resource Sharing (CORS)