Reading table:

(1) – Understanding cross-domain resource sharing of CORS;

Deep Cross-domain Problems (2) – Solving cross-domain Problems using CORS

Deep cross domain Problems (3) – Using JSONP to solve cross domain problems

Deep cross – domain problems (4) – cross – domain solutions using proxy servers

Answer the question:

Read the first article before reading this one for better results!! Answer the question from the previous article:

  1. A pre-request is not triggered because it is a simple GET method.
  2. Not triggerAdvance request, is a simple POST method, jquery uses it by defaultapplication/x-www-form-urlencoded.
  3. Will triggerAdvance request, although it is a POST method, butContent-Typeapplication/json. Not in the three cases above,text/plainmultipart/form-data.application/x-www-form-urlencoded

The third point, is the most important point, but also often wrong point, remember to trigger the pre-request three cases!!

Building a cross-domain environment:

Simulate client request:


      
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Ajax test</title>
</head>
<body>
    <script src="./node_modules/jquery/dist/jquery.min.js"></script>
    <script>
        $.ajax({
            url: "http://localhost:3000".type: "get".success: function (result) {
                console.log(result);
            },
            error: function (msg) {
                console.log(msg); }})</script>
</body>
</html>
Copy the code

NPM install jquery is also available for download.

Simulate server response, create app.js file, paste and run:

const http = require('http');

const server = http.createServer((request, response) = > {
    if (request.url === '/') {
        if (request.method === 'GET') {
            response.end("{name: 'BruceLee', password: '123456'}");
        }
        
        if (request.method === 'POST') {
            response.end("true");
        }
    }

    response.end('false');
});

server.listen(3000, () = > {console.log('The server is running at http://localhost:3000');
});
Copy the code

Ok, now double-click on the HTML file to open it:

Obviously, this is a cross-domain error.

Process non-pre-requests

In both of these examples, we said that the POST and GET methods can implement non-pre-requests.

Key code: set a response header field to allow CORS to share resources across domains:

response.writeHead(200, {
  'Access-Control-Allow-Origin': '*
}
Copy the code

In this case, we set it to be accessible to all clients.

Complete code:

const http = require('http');

const server = http.createServer((request, response) = > {
    if (request.url === '/') {
        if (request.method === 'GET') {
            
            response.writeHead(200, {
                'Access-Control-Allow-Origin': The '*' // Key code
            });
            
            response.end("{name: 'BruceLee', password: '123456'}");
        }
        
        if (request.method === 'POST') {
            
            response.writeHead(200, {
                'Access-Control-Allow-Origin': The '*' // Key code
            });
            
            response.end("true");
        }
    }

    response.end('false');
});

server.listen(3000, () = > {console.log('The server is running at http://localhost:3000');
});
Copy the code

Front-end test code:

$.ajax({
    url: "http://localhost:3000".type: "get".success: function (result) {
        console.log(result);
    },
    error: function (msg) {
        console.log(msg); }})var data = { name: 'BruceLee'.password: '123456' };

$.ajax({
    url: "http://localhost:3000".type: "post".data: JSON.stringify(data),
    success: function (result) {
        console.log(result);
    },
    error: function (msg) {
        console.log(msg); }})Copy the code

Execution Result:

Handling non-pre-requests is as simple as setting a response header field in the background.

Note: When we use the POST method, Jquery uses it by defaultContent-Type: application/x-www-form-urlencoded, so it will not trigger a pre-request!!

In fact, not only Jquery, but axios and other libraries that encapsulate Ajax are adopted by defaultContent-Type: application/x-www-form-urlencoded!!!!!!!!!

Process POST pre-requests

All pre-requests, not just posts, are handled the same.

The POST method triggers a pre-request when contentType is set to Application /json.

Front-end test code:

var data = { name: 'BruceLee'.password: '123456' };

$.ajax({
    url: "http://localhost:3000".type: "post".data: JSON.stringify(data),
    contentType: 'application/json; charset=utf-8'.success: function (result) {
        console.log(result);
    },
    error: function (msg) {
        console.log(msg); }})Copy the code

Note that the contentType has been changed to Application /json, in which case the pre-request is triggered! ! !

Node server code:

const http = require('http');

const server = http.createServer((request, response) = > {
    if (request.url === '/') {
        if (request.method === 'GET') {
            response.writeHead(200, {
                'Access-Control-Allow-Origin': The '*'
            });
            response.end("{name: 'BruceLee', password: '123456'}");
        }

        if (request.method === 'POST') {
            response.writeHead(200, {
                'Access-Control-Allow-Origin': The '*'
            });

            response.end( JSON.stringify({state: true})); }if (request.method === 'OPTIONS') {	
    		
            response.end( JSON.stringify({state: true})); } } response.end('false');
});

server.listen(3000, () = > {console.log('The server is running at http://localhost:3000');
});
Copy the code

Here, we added the logic to handle the OPTIONS method.

Test results:

We did not set the CORS response header field inside the OPTIONS method.

Modify code, key code:

if (request.method === 'OPTIONS') {	
    response.writeHead(200, {
        'Access-Control-Allow-Origin': The '*'.// Set the optins method to allow access by all servers
        'Access-Control-Allow-Methods': The '*'.// Allow access to all methods such as POST, PUT, and DELETE
    });		
    response.end( JSON.stringify({state: true})); }Copy the code

In the Node code, we add processing for OPTIONS and set the POST method to allow access.

After modifying the code, restart the server and refresh the HTML page. The result is:

Here, there is still a problem, according to the description of the error, we should setAccess-Control-Allow-HeadersResponse header field.

Key code:


if (request.method === 'OPTIONS') {	
    response.writeHead(200, {
        'Access-Control-Allow-Origin': The '*'.// Set the optins method to allow access by all servers
        'Access-Control-Allow-Methods': The '*'.// Allow access to all methods such as path '/' POST
        'Access-Control-Allow-Headers': 'Content-Type'.// Allow content-Type headers
    });	
    response.end( JSON.stringify({state: true})); }Copy the code

We need to set up to allow access to Content with a content-Type header.

Complete code:

const http = require('http');

const server = http.createServer((request, response) = > {
    if (request.url === '/') {
        if (request.method === 'GET') {
            response.writeHead(200, {
                'Access-Control-Allow-Origin': The '*'
            });
            response.end("{name: 'BruceLee', password: '123456'}");
        }

        if (request.method === 'POST') {
            response.writeHead(200, {
                'Access-Control-Allow-Origin': The '*'
            });

            response.end( JSON.stringify({state: true})); }if (request.method === 'OPTIONS') {	
            response.writeHead(200, {
                'Access-Control-Allow-Origin': The '*'.// Set the optins method to allow access by all servers
                'Access-Control-Allow-Methods': The '*'.// Allow access to all methods such as path '/' POST
                'Access-Control-Allow-Headers': 'Content-Type'.// Allow content-Type headers
            });
        }
    }

    response.end('false');
});

server.listen(3000, () = > {console.log('The server is running at http://localhost:3000');
});
Copy the code

Execution Result:

  1. Advance request

  2. A POST request

That completes the processing of the pre-request. Now you can tell the backend that you did not handle the OPTIONS method!!

Ok, so here you have the basic pre-request processing solution.

Conclusion:

  1. Cross-domain resource sharing using CORS needs to be divided into pre-request and non-pre-request processing.

  2. Non-pre-request, within the server, requires a simple setup:

    'Access-Control-Allow-Origin': '*
    Copy the code
  3. Pre-request, at least three response head fields must be set within the server:

    'Access-Control-Allow-Origin':? .'Access-Control-Allow-Methods':? .'Access-Control-Allow-Headers': 'Content-Type'.Copy the code
  4. When using content-Type: application/json on the front end, it is important to note that this is a pre-request and the back end needs to handle the OPTIONS method

Reference and Acknowledgements:

  • Ruan Yifeng, Cross-domain resource sharing CORS;
  • Browser same Origin Policy and its Circumvention Ruan Yifeng;
  • HTTP Access Control (CORS) MDN document;

I wish you a happy coding, if you like it, click a “like” and then go!!