What is a cross-domain request

The domain in which the request is being made is different from the domain in which the resource to which the request is directed (the page on which the request is located) is located.

In this case, the request is restricted by the browser SOP (same Origin policy). This reduces the possibility of CSRF (cross-site request forgery) attack, but the same origin policy does not prevent CSRF. Those interested in CSRF can read more here.

The domain here refers to the concept that if the protocol + domain name + port number are the same, it is the same domain.

How can AJAX cross domains be solved

  • JSONP
  • CORS
  • The agent requests
  • Pictures Ping
  • websocket

(I) JSONP method to solve cross-domain problems

JSONP is an ancient solution to cross-domain problems (it is not recommended in practice), so here is a brief introduction. (In real projects, JSONP is usually used to make Ajax requests using JSONP wrapped libraries such as JQuery.)

Realize the principle of

JSONP can be used to solve cross-domain solutions mainly because < Script > scripts have cross-domain capabilities, and JSONP takes advantage of this.

When we request an interface with a script SRC, the interface returns a function name and one or more parameters. Since script introduced, the browser simply executes it for us. Note that we must register the method returned by the interface before doing so.

The implementation process

The implementation steps of JSONP are as follows

Client web page A web page requests JSON data from the server by adding a

function addScriptTag(src) {
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}

window.onload = function () {
  addScriptTag('http://example.com/ip?callback=foo');
}

function foo(data) {
  console.log('response data: ' + JSON.stringify(data));
};
Copy the code

The interface address is requested as the SRC of the script tag being built, so that when the script tag is built, the final SRC is what the interface returns

The corresponding interface on the server adds a function wrapper around the return parameters

foo({
  "test": "testData"
});  
Copy the code

The script requested by the

Use attention

JSONP is based on the implementation principle of JSONP, so JSONP can only be a “GET” request, can not carry out more complex POST and other requests, so in that case, we have to refer to the following CORS to solve the cross-domain

(2) CORS solves cross-domain problems

CORS (Cross-Origin Resource Sharing) is a system that consists of a series of transmitted HTTP headers that determine whether the browser prevents front-end JavaScript code from getting a response to a cross-domain request.

By default, the same-origin security policy prevents cross-domain access to resources. But CORS gives Web servers the option to allow cross-domain requests to access their resources.

He allows us to set some request headers to address cross-domain:

Access-control-allow-origin // indicates to which domains the requested resource can be shared. Access-control-allow-credentials // Indicates whether to respond to a request when the requested Credentials are marked true. Access-control-allow-headers // Used in a response to a pre-request to indicate which HTTP Headers can be used in the actual request. Access-control-allow-methods // Specifies which HTTP Methods in the response to a pre-request Allow Access to the requested resource. Access-control-expose-headers // indicates which HTTP header names can be listed in the response. Access-control-max-age // indicates how long the pre-requested results can be cached. Access-control-request-headers // Is used to initiate a pre-request, telling the server which HTTP Headers will be used for a formal Request. Access-control-request-method // Is used to initiate a pre-request that tells the server which HTTP Request Method will be used for the formal Request. Origin // indicates the domain from which the request for the resource originated.Copy the code

In addition, the specification requires that HTTP request methods (especially HTTP requests other than GET, or POST requests paired with certain MIME types) that may have adverse effects on server data, The browser must first issue a preflight request using the OPTIONS method to know if the server will allow the cross-source request. The actual HTTP request is made only after the server confirms that it is allowed

In the return of the precheck request, the server side can also inform the client whether it needs to carry identity credentials (including Cookies and HTTP authentication related data).

CORS request failures generate errors, but for security reasons, there is no way to know exactly what went wrong at the JavaScript code level. You can only look at your browser’s console to see exactly what went wrong.

However, not all requests will have a precheck request. For more information, read the MDN documentation on Cross-source Resource Sharing (CORS).

(3) Proxy request method to solve the interface cross domain problem

Note that this is generally only used during development, since interface proxies come at a cost.

Different from the previous method, the previous CORS is the back-end solution, and this is mainly the front end to proxy the interface, that is:

The front-end ajax requests the local interface and the local interface receives the request and requests the data to the actual interface, and then sends the information back to the front-end. Generally, nodeJS is the proxy. There are many ways to implement the proxy, so we usually use Webpack-dev-server,

If we are serving localhost:3000, you can enable the proxy as follows:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: {'^/' : ''}
      }
    }
  }
};
Copy the code

Request to the/API/users will now be agent to request http://localhost:3000/api/users.

If you don’t want to pass/API all the time, you need to rewrite the path:

webpack.config.js

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: {'^/api' : ''}
      }
    }
  }
};
Copy the code

Http-proxy-middleware is used to delegate middleware to http-proxy-Middleware. If you’re interested, check out the source code for more information

(4) Picture Ping

We know that a web page can load images from any web page without worrying about cross-domain, so we can take advantage of the fact that images are not subject to “homology restriction” for cross-domain communication.

We use JS to create a new Image object, set the SRC property to the requested address, and listen for onLoad and onError events to determine whether the response was received. The data for the response can be anything, but it is usually a pixel map or a 304 response.

Note that new image elements are downloaded as soon as the SRC attribute is set, so our events must be bound before the SRC attribute is specified, which is why we don’t need to insert the IMG tag into the DOM.

</button> <script> var BTN = document.getelementbyid ('Ping'); btn.onclick=function () { var img=new Image(); img.onload=img.onerror=function () { alert("Done"); }; img.src="http://localhost:8081/img? name=Joy"; } </script> </body> app.get('/img',function (req,res) {res.send(" I am a picture "); });Copy the code

The advantages of this approach are obvious: compatibility is very good, but the disadvantage is that only GET requests can occur and no response text can be obtained.

(5) the WebSocket

WebSockets are an advanced technology. It opens an interactive communication session between the user’s browser and the server. Using this API, you can send messages to the server and receive event-driven responses without having to poll the server for a response.

It is cross-domain by default.

// Create WebSocket connection. const socket = new WebSocket('ws://localhost:8080'); // Connection opened socket.addEventListener('open', function (event) { socket.send('Hello Server! '); }); // Listen for messages socket.addEventListener('message', function (event) { console.log('Message from server ', event.data); });Copy the code

For cross-domain between front-end pages

  • If it is an iframe, you can use location.hash or window.name to communicate information
  • Using postMessage
  • Document.domain (between level 1 domain and Level 2 domain only)

Reference

  • A summary of Ajax cross – domain by Ali
  • WebSockets MDN
  • Cross-source resource sharing (CORS) MDN

One More Thing

Welcome to follow my personal public numberMr. Wang, who likes to do things

PS: Attention has welfare oh ~