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)