Follow the public account “Kite”, reply to “little Red Book” to get “javaScript Advanced program 4th edition (PDF)” and a lot of front-end learning materials.
The cross-domain question has always been a classic interview question, which has been encountered by both experienced and new candidates. One of the ultimate solutions to cross-source Ajax requests is CORS (Cross-source resource sharing), a term we use to spout a lot of theoretical knowledge, but we do a lot of recitation, we rarely test every theoretical point. In this section, we will verify these theoretical points through experiments and thoroughly understand CORS through the combination of theory and practice.
First, theoretical knowledge
Since it is CORS, it must be too much to recite these theoretical points. I will use three pictures to make some simple summaries of this theory
1.1 Request Types
1.1.1 Simple Request
1.1.2 Non-simple Requests
1.2 How to Include Cookie Information in a Request
Second, the experimental
Prepare for the experiment, including an HTML page and a server program, where the HTML access url is http://127.0.0.1:8009; The server listening port is 8010.
- HTML page initial code
<! DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>test CORS</title> </head> <body> CORS <script SRC = "https://code.bdstatic.com/npm/[email protected]/dist/axios.min.js" > < / script > < script > axios (' http://127.0.0.1:8010 ', { method: 'get' }).then(console.log) </script> </body> </html>Copy the code
- Server-side code (with express framework)
const express = require('express'); const app = express(); App.get ('/', (req, res) => {console.log('get request received!! '); Res.send (' Get request has been processed '); }) app.listen(8010, () => { console.log('8010 is listening') });Copy the code
The experiment 2.1 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.
2.2 the second
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.
2.3 the 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)
2.4 the 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 kite, receive learning materials, regularly push original depth of good articles for you