当前位置:网站首页>Combine theory with practice to understand CORS thoroughly

Combine theory with practice to understand CORS thoroughly

2020-11-08 23:46:00 Xiake Alliance Technology Institute

Official account “ Kite holder ”, reply “ Red Treasure Book ” obtain “ javaScript Advanced program Fourth Edition (pdf)” And a lot of front-end learning materials .

Cross domain question has always been a classic question in interview , Whether it's the old bird or the new bird in the front end . Which is for cross source Ajax There is an ultimate solution in the request ——CORS( Cross source resource sharing ) You must be no stranger , When you say this noun , We will come out with a set of theoretical knowledge , But there's a lot of theoretical knowledge that we just recite , Rarely to test every theoretical point , In this section, we will verify these theoretical points through experiments , To understand thoroughly through the combination of theory and practice CORS.

One 、 Theoretical knowledge

Since it is CORS, It's not too much to recite these theories , I will use three pictures to make some simple summary of this theory

1.1 Request type

1.1.1 A simple request

1.1.2 It's not a simple request

1.2 Ask how to bring Cookie Information

Two 、 experiment

Prepare for the experiment , Contains a html Page and a server program , among html The website is http://127.0.0.1:8009; The server listener 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>
  1. Server-side code ( use express frame )
const express = require('express');

const app = express();

app.get('/', (req, res) => {
    console.log('get The request was received !!!');
    res.send('get The request has been processed ');
})
app.listen(8010, () => {
    console.log('8010 is listening')
});

2.1 Experiment 1

The experiment purpose :

  1. Non homologous can cause cross domain problems
  2. Cross domain is caused by the browser's response interception
  1. First, let's take a look at the browser console content

Console content display error , The content of error report is cross domain , This is because the ports are different ( One 8009 One 8010), The two are not homologous , So it leads to cross domain , The purpose of the experiment is verified 1.
  1. Next, let's see what the server console prints

The contents of the console are printed and received get request , It proves that the request of browser is sent and received by server , It is proved from the side that cross domain is that the browser intercepts the response , The purpose of the experiment is verified 2.

2.2 Experiment two

The experiment purpose

  1. Server configuration Access-Control-Allow-Origin Will solve cross domain problems
  2. The browser uses whether the response header contains Access-Control-Allow-Origin The value of this response header is the same as that in the request header Origin Is equal to determine whether cross domain access is possible
  1. First of all, take a look at the request head

  1. And then take a look at the response head

In theory , In the request header Origin Field indicates which source the request came from ( agreement + domain name + port ), Based on this value, the server decides whether to agree to the request . If Origin The specified source is not within the scope of the license , The server will return a normal HTTP Respond . There is no change at the moment , Still in error reporting state , The response is really a normal response , It doesn't contain Access-Control-Allow-Origin Field , But it's not enough to convince me that browsers actually allow cross domain requests by verifying this field . So then we need to do a comparative experiment , After modifying the server code, observe the response header content .
  1. Start with the simplest changes , Add... Directly to the response header Access-Control-Allow-Origin=“http://127.0.0.1:8009” Field , In theory, all cross domain requests will be allowed at this time .
After the server code is modified
app.get('/', (req, res) => {
    console.log('get The request was received !!!');
    res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:8009');
    res.send('get The request has been processed ');
})
Response header content

An extra line was observed in the response header :Access-Control-Allow-Origin:http://127.0.0.1:8009 Field , Looking at the response content , There's a message coming back , The contents are as follows :

  1. Only verified. Origin and Access-Control-Allow-Origin In response to the content of , What will happen if the content is different ?
The server code is further modified
app.get('/', (req, res) => {
    console.log('get The request was received !!!');
    res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:8008');
    res.send('get The request has been processed ');
})
Response header content

At this time, the browser console reported an error , There's a cross domain problem

Through this experiment, we can verify that through the configuration Access-Control-Allow-Origin Fields can solve cross domain problems ; Besides , The browser checks the response header by Access-Control-Allow-Origin The value of the field is the same as Origin To determine whether cross domain access is allowed . The purpose of our experiment is achieved through this experiment .

2.3 Experiment three

The experiment purpose
verification CORS The request is not sent by default Cookie Information , If you want to put the Cookie Send to server , On the one hand, the server should agree to ( By designation Access-Control-Allow-Origin Field and Access-Control-Allow-Origin You need to specify a specific domain name ); On the other hand, browser requests must be accompanied by withCredentials Field .
  1. By looking at the request header ( Look at the request header in Experiment 1 ), Does not contain Cookie Information
  2. Code changes
index.html Page changes
axios('http://127.0.0.1:8010', {
    method: 'get',
    withCredentials: true
}).then(console.log)
Server side code modification
app.get('/', (req, res) => {
    console.log('get The request was received !!!');
    console.log('cookie  The 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 The request has been processed ');
})
  1. Look at the request header again , Take with you cookie

  1. See if the server has received cookie Information , The console information is as follows , I did cookie Information

According to the above configuration, the request will be sent with cookie Information , The last configuration will report an error ( Can self verify )

2.4 Experiment four

The experiment purpose

  1. Verifying a non simple request will add a pre check request
  2. The pre inspection request is Options request
  3. The request header will carry the request method of a non simple request (Access-Control-Request-Methods) And header information (Access-Control-Request-Headers), In the response header of the pre check request Access-Control-Allow-Methods and Access-Control-Allow-Headers Only by matching the information in the above request header can normal CORS request .
  1. The first step must be to modify 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)
The server code is modified as follows
app.options('/', (req, res) => {
    console.log('options The request was 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 The request has been processed ');
});

app.post('/', (req, res) => {
    console.log('post The request was received !!!');
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.send('post The request has been processed ');
});
  1. Do you want to see the result after modifying the code ?
Let's see if the browser outputs the content , There's something out there

Take a look at what the server outputs

You can see that you were going to make a request , But actually there were two , The first is Options request , The second request is post request , The above printed content verifies one and two of the purposes of the experiment .

  1. Let's continue to think deeply , Let's take a look at the request and response headers of the preview request
Request header content

Response header content

Above Access-Control-Request-Headers And Access-Control-Allow-Headers equally , And the content returned normally ( Step two has already shown ), But this is not enough to prove the purpose of the experiment , Now we think we can add a header to see the result .

  1. Add a request header artificially
index.html The 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)
At this time, the browser console reported an error

The server only receives options request

The request header information is

The response header information is

Through this experiment, only Access-Control-Request-Headers And Access-Control-Allow-Headers On equal terms , The pre inspection request will pass , A subsequent request will be sent , Thus, the purpose of the experiment is achieved .

1. If you think this article is good , Let's share 、 Praise it. , Let more people see

2. Pay attention to the official account of the kite , Get the learning materials , Regular push for you original depth good article

image

image.png

版权声明
本文为[Kite holder]所创,转载请带上原文链接,感谢