Understand several cross-domain solutions and experience them through simple practice.

How to practice?

But how do we do that? Where to make the request? What server is the request made to? Very simple, just on the current web page, open the console, enter the request code

Var url = 'http://127.0.0.1:8888/'; var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.send();Copy the code

So we can use the current page URL as the origin and send a GET request to http://127.0.0.1:8888/. Create a Node service locally

var http = require('http'); http.createServer(function (request, response) { response.writeHead(200, { 'Content-Type': 'text/plain' }); response.end('request success!!! '); }).listen(8888); The console. The log (' Server running at http://127.0.0.1:8888/);Copy the code

So we have a server that you can easily follow through this article and then send a GET request from the current web page to the local service, cross-domain of course.

This error is used to prevent content injection attacks. It has to be said that large sites have done a good job in security measures. Switch to the SegmentFault.

1. cors

Cors (Cross-origin Resource Sharing) allows browsers to issue XMLHttpRequest requests to cross-domain servers to overcome cross-domain problems. It requires both browsers and servers to support it.

Cors is divided into two types of request, simple request and non-simple request. For a more detailed introduction of CORS, I recommend teacher Ruan Yifeng’s detailed explanation of cross-domain resource sharing CORS. This paper focuses on practice.

A simple request

The example above is a simple request

Var url = 'http://127.0.0.1:8888/'; var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.send();Copy the code

How to solve the cross-domain problem in this case?

  1. On the browser side, the browser will automatically add the Origin field to the request header, so we don’t need to operate.
Request Headers: 
Origin: https://github.com
Copy the code
  1. Access-control-allow-origin = access-Control-allow-origin = access-Control-allow-origin = access-Control-allow-origin*To specify all domain names. The back end is moving:
var http = require('http'); http.createServer(function (request, response) { response.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': '*' }); response.end('request success!!! '); }).listen(8888); The console. The log (' Server running at http://127.0.0.1:8888/);Copy the code

Restart the service and try again



No error this time, let’s see what the server put back



Nice! Cross-domain success!

Non-simple request

Again, let’s type in the code on the console to do put (non-simple request)

Var url = 'http://127.0.0.1:8888/'; var xhr = new XMLHttpRequest(); xhr.open('PUT', url, true); xhr.send();Copy the code

No unexpected errors were reported

When making a non-simple Request, the browser will send an OPTION Request to “preflight” whether the Request is allowed or not. Access-control-request-method is used in the Request header. Access-control-request-headers tells the server that I need to use the method or field. The server returns the access-Control-allow-Origin header information. Access-control-allow-method tells the browser whether the cross-domain request is allowed. Modify the backend code:

var http = require('http'); http.createServer(function (request, response) { response.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT' }); response.end('request success!!! '); }).listen(8888); The console. The log (' Server running at http://127.0.0.1:8888/);Copy the code

You can see that the browser sends a precheck

When it is confirmed that cross-domain is allowed, the request is sent later, eliminating the precheck processing and treating it as a simple request. Obviously, after modifying the backend code, the PUT request was successful. I’m not going to continue with the figure above.

Cors summary

Cors (Cross-origin Resource Sharing) allows browsers to issue XMLHttpRequest requests to cross-domain servers to overcome cross-domain problems. It requires both browsers and servers to support it.

  1. The browser automatically adds the Origin field to the request header to indicate the source of the current request.
  2. The browser needs to set the response headerAccess-Control-Allow-Methods.Access-Control-Allow-Headers.Access-Control-Allow-Origin, specifying allowed methods, headers, sources, etc.
  3. Requests are classified into simple requests and non-simple requests. For non-simple requests, the OPTION method is used to pre-check whether the current cross-domain request is allowed.

2. jsonp

The jSONP principle is that there are no cross-domain restrictions on using script tags. GET requests can be sent via the SRC attribute of script tags. We continue to try to remove the cross-domain Settings from the back end and restart the service

var http = require('http'); http.createServer(function (request, response) { response.writeHead(200, { 'Content-Type': 'text/plain' }); response.end('request success!!! '); }).listen(8888); The console. The log (' Server running at http://127.0.0.1:8888/);Copy the code

Open our console and enter the code to make a JSONP request using the script tag

var script = document.createElement('script'); script.type = 'text/javascript'; Script. The SRC = ` http://127.0.0.1:8888/ `; document.head.appendChild(script);Copy the code

As you can see, the back end returns normally

request success !!!Copy the code

And the request is a GET request

Request URL: http://127.0.0.1:8888/ Request Method: GET Status Code: 200 OK Remote Address: 127.0.0.1:8888 Referrer Policy: no - Referrer - the when - downgradeCopy the code

But now we’ve just successfully sent a cross-domain request, and unlike XMLHttpRequest, we can get the data in res.responseText. How do we get the data in jSONP? The front end uses a callback field name to pass in the function name. The front-end code was changed to:

var script = document.createElement('script'); script.type = 'text/javascript'; Script SRC = ` http://127.0.0.1:8888/? callback=onBack`; document.head.appendChild(script); function onBack (res) { console.log(JSON.stringify(res)); Var head = document.head head. RemoveChild (script)} var head = document.head head.Copy the code

Pass the function name onBack through the callback field, the back-end code is changed to

Var data = {'methods': 'jsonp', 'result': 'success'}; http.createServer(function (request, response) { var params = urlTool.parse(request.url, true) console.log(params) response.writeHead(200, { 'Content-Type': 'text/plain' }); if (params.query && params.query.callback) { // callback(data) var str = `${params.query.callback}(${JSON.stringify(data)})` } response.end(str); }).listen(8888); The console. The log (' Server running at http://127.0.0.1:8888/);Copy the code

Restart the back-end service and enter the code on the console, and you can see the result:

We get the data and print it to the console using the onBack function!

conclusion

  1. Jsonp is a cross-domain scheme that he utilizesscriptTags have no cross-domain limiting features throughscriptThe SRC attribute of the tag is sentGETThe request.
  2. You can pass a function name by specifying a field name, such as callback, so that the front end can use the corresponding callback function to fetch and process the data.

Compare JSONP and CORS

  1. CORS serves the same purpose as JSONP, but is more powerful than JSONP.
  2. JSONP supports only GET requests, and CORS supports all types of HTTP requests. JSONP has the advantage of supporting older browsers and being able to request data from sites that do not support CORS.

The same origin policy: The same origin policy restricts how loaded text or scripts from one origin can interact with resources from other sources, which is an important security mechanism used to isolate potentially malicious files. If two pages have the same protocol, port (if specified), and host, then they belong to the same origin.