“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”
The original intention of this series of articles is to “let each front-end engineer master the high frequency knowledge, for the work of power”. This is the front end of the 27th cut, I hope friends pay attention to the public number “kite”, armed with knowledge of their minds.
27.1 introduction
By default, browsers don’t allow XMLHttpRequest objects to access resources on different sites, according to the same origin policy. This can be a huge productivity constraint, so you need a mechanism to allow cross-domain access to resources. Then our hero, CORS (Cross-domain resource Sharing), comes in. Therefore, cross-domain data transmission can be carried out safely.
27.2 Overall process
The communication process of CORS is automatically completed by the browser without user participation. Its core point is the server. As long as the server implements THE CORS interface, cross-source communication can be realized. Although this is done automatically by the browser, the browser is actually divided into simple requests and non-simple requests based on the difference in the field of the request. The following is a brief description of both.
27.2.1 Simple Request
27.2.1.1 definition
A simple request is one that meets the following two conditions:
- The request method is one of three methods: HEAD, GET, and POST.
- HTTP headers do not exceed the following fields: Accept, accept-language, Content-language, last-event-id, Content-Type (its values are Application/X-www-form-urlencoded, multipart/form-d) Ata, text/plain).
27.2.1.2 process
The entire process of a simple request can be summed up in the following steps:
- The browser directly sends the CORS request. Specifically, it adds an Origin field in the header information, which indicates the source (protocol + domain name + port) from which the request comes. The server decides whether to approve the request based on this value.
- When the server receives the request, Origin determines whether the specified source is within the licensed range.
- If not, the server returns a normal HTTP response, and when the browser finds that the response header does not contain the Access-Control-Allow-Origin field, it knows something is wrong and throws an error that is caught by XML’s onError callback function. (Note: This error is not recognized by the status code because the status code is 200 for a normal response.)
- If Origin specifies a domain name within the license, Several Header fields (access-Control-allow-Origin, access-Control-allow-credentials, access-Control-expose-header, etc.) are added to the response returned by the server.
27.2.1.3 Key Fields
- Access-Control-Allow-Origin
Required field, which is either the Origin field value of the request or an * (to accept requests for any domain name).
- Access-Control-Allow-Credentials
Optional field whose value is a Boolean value indicating whether cookies are allowed to be sent. The default is not to send a Cookie value. When set to true, the server explicitly allows cookies to be included in the request and sent to the server. (Note: When sending cookies, note that the withCredentials attribute needs to be set in the Ajax request. Access-control-allow-origin cannot be set to *. You need to specify a specific domain name that corresponds to the requested page.
- Access-Control-Expose-Header
Optional field, when CORS requests, The getResponseHeader() method of the XMLHttpRequest object takes only six basic fields (cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragm) A), if you want to obtain other fields must be specified in access-Control-expose-header.
27.2.2 Non-simple Requests
27.2.2.1 definition
Non-simple requests are non-simple requests. Non-simple requests are requests that have special requirements on the server, for example, the request method is PUT or Delete, or the content-Type field is application/ JSON.
27.2.2.2 process
A non-simple request is more complex than a simple request. A pre-check request is performed before a formal request is sent. The result of the pre-check request is used to determine whether to conduct subsequent formal communication.
- The browser initiates a precheck request, the request method is options, the request is used to ask;
- After receiving the pre-check Request, the server checks the Origin, Access-Control-request-Method, and access-Control-request-headers fields, and confirms that cross-source requests are allowed.
- If the browser denies the precheck request and returns a normal HTTP response without any CORS related header fields, the browser will assume that the server did not approve the precheck request and trigger an error.
- If the browser passes the “precheck” request, every normal CORS request from the browser will have the same Origin header field as a simple request, and the server will also have an Access-Control-Allow-Origin header field.
27.2.2.3 Key fields
- Access-Control-Request-Method
A required field that lists which HTTP methods are used for the browser’s CORS request.
- Access-Control-Request-Headers
This field is a comma-separated string that specifies the additional header fields that the browser will send for CORS requests.
- Access-Control-Allow-Methods
Required field, the value of which is a comma-separated string that identifies all methods supported by the server for cross-domain requests.
- Access-Control-Allow-Headers
The value is a comma-separated string indicating all header information fields supported by the server.
- Access-Control-Max-Age
Used to request the validity period of a precheck request, in seconds.
27.3 the
27.3.1 experiment a
Experimental purpose:
- Non-homology causes cross-domain problems
- Cross-domain is caused by browser response interception
- Let’s start with the browser console content
Console content display error, error content is cross-domain, this is because the port is different (one 8009 and one 8010), they are different sources, so cross-domain, verify experimental purpose 1.
- Next, take a look at what the server console prints
The console printed that the GET request was received, which proved that the browser’s request was sent and received normally by the server. It proved from the side that it was the browser that intercepted the response across domains, thus verifying experimental purpose 2.
27.3.2 experiment 2
The experiment purpose
- Configuring access-Control-allow-Origin on the server solves the cross-domain problem
- The browser determines whether cross-domain Access is possible by checking whether the value of the access-Control-Allow-Origin response header is equal to the value of the Origin in the request header
-
First take a look at the request header
-
A quick look at the response header
In theory, the Origin field in the request header indicates the source (protocol + domain + port) from which the request is coming. The server uses this value to decide whether to approve the request or not. If Origin does not specify a licensed source, the server returns a normal HTTP response. The response is indeed a normal response and does not contain the Access-Control-Allow-Origin field, but this is not enough to convince me that the browser validates this field to confirm whether cross-domain requests are allowed. So the next step is to do a comparative test by modifying the server-side code to look at the response header content.
- Starting with the simplest modification, adding the access-Control-Allow-Origin = “http://127.0.0.1:8009” field directly to the response header should theoretically Allow all cross-domain requests at this point.
Modified contents of server code
App.get ('/', (req, res) => {console.log('get request received!! '); Res. SetHeader (' Access - Control - Allow - Origin ', 'http://127.0.0.1:8009'); Res.send (' Get request has been processed '); })Copy the code
Response header content
Access-control-allow-origin: http://127.0.0.1:8009 = access-Control-allow-origin: http://127.0.0.1:8009 = access-Control-allow-origin: http://127.0.0.1:8009
- Only the Origin and access-Control-allow-Origin content responses are validated. What if the content is different?
The server code has been further modified
App.get ('/', (req, res) => {console.log('get request received!! '); Res. SetHeader (' Access - Control - Allow - Origin ', 'http://127.0.0.1:8008'); Res.send (' Get request has been processed '); })Copy the code
Response header content
The browser console is reporting an error and a cross-domain problem has occurred
Through this experiment, it can be verified that cross-domain problems can be solved by configuring the access-Control-allow-Origin field. In addition, the browser determines whether to Allow cross-domain Access by checking whether the value of the Access-Control-Allow-Origin field in the response header is equal to the value of Origin. The purpose of our experiment was achieved through this experiment.
27.3.3 experiment three
CORS requests do not send Cookie information by default. If cookies are to be sent to the server, Access-control-allow-origin specifies the domain name of the access-Control-allow-origin field. On the other hand, the withCredentials field must be included in the browser request.
- By looking at the request header (see the request header in Experiment 1), there is no Cookie information
- Code changes
The index. HTML page is modified
Axios ('http://127.0.0.1:8010', {method: 'get', withCredentials: true}).then(console.log)Copy the code
Server side code modification
App.get ('/', (req, res) => {console.log('get request received!! '); Console. log('cookie content is ', req.headers. Cookie); Res. SetHeader (' Access - Control - Allow - Origin ', 'http://127.0.0.1:8009'); res.setHeader('Access-Control-Allow-Credentials', true); res.cookie('test', 'test', {expires: new Date(Date.now() + 900000)}); Res.send (' Get request has been processed '); })Copy the code
-
Look again at the request header content, with the cookie attached
-
Check whether the server received the cookie message. The console information is as follows: Yes, it received the cookie message
Following the above configuration will send the request with cookie information, the previous configuration will report an error (you can verify yourself)
27.3.4 experiment four
The experiment purpose
- Verifying non-simple requests adds a precheck request
- The precheck request is an Options request
- The Request header carries the access-Control-request-methods and the access-Control-request-headers for non-simple requests. A normal CORS request can be sent only when access-Control-allow-methods and access-Control-allow-headers in the response header of the pre-check request match the preceding information.
- The first step is definitely to change the code
Index.html code
Axios ('http://127.0.0.1:8010', {method: 'post', headers: {' content-type ': 'application/json'}, data: {name: 'dog' } }).then(console.log)Copy the code
The server code is modified as follows
App.options ('/', (req, res) => {console.log(' Options request received!!! '); res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); res.setHeader('Access-Control-Max-Age', 10000); Res. send(' Options request already processed '); }); App.post ('/', (req, res) => {console.log('post request received!!! '); res.setHeader('Access-Control-Allow-Origin', '*'); Res.send (' Post request has been processed '); });Copy the code
- After modifying the code, do you want to see the result?
Let’s see if the browser is sending something, and it is sending something
What is the output of the server
The first request is an Options request, and the second request is a POST request. The printed content above verifies the first and second of the experimental purposes.
- Let’s take a closer look at the request and response headers for prechecked requests
Request header content
Response header content
Access-control-request-headers is the same as access-Control-allow-headers, and the content is returned normally (as shown in Step 2), but this is not sufficient to prove purpose 3. Now let’s say we add a header and look at the result.
- Add a request header manually
The index. HTML page is modified as follows
Axios ('http://127.0.0.1:8010', {method: 'post', headers: {' content-type ': 'application/json', 'Test': 'Test'}, data: { name: 'dog' } }).then(console.log)Copy the code
The browser console is reporting an error
The server received only options requests
The request header is
The response header information is
Through this experiment, it is proved that only when access-Control-request-headers is equal to access-Control-allow-headers, the pre-check Request will pass and the subsequent Request will be sent, thus achieving the third experimental purpose of this experiment.
1. If you think this article is good, share and like it so that more people can see it
2. Pay attention to the public number of kite, and the number of the Lord together to kill the front hundred