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.

  1. 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
  1. 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:

  1. Non-homology causes cross-domain problems
  2. Cross-domain is caused by browser response interception
  1. 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.

  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

  1. Configuring access-Control-allow-Origin on the server solves the cross-domain problem
  2. 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
  1. First take a look at the request header

  1. 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.

  1. 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

  1. 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.

  1. By looking at the request header (see the request header in Experiment 1), there is no Cookie information
  2. 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
  1. Look again at the request header content, with the cookie attached

  1. 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

  1. Verifying non-simple requests adds a precheck request
  2. The precheck request is an Options request
  3. 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.
  1. 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
  1. 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.

  1. 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.

  1. 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