preface

First of all, what is the same origin policy? The same origin policy is a security policy proposed by Netspace. A homologous source is defined by the protocol, host, and port of a URL. If the three are consistent, the source is homologous.

What operations are allowed when different sources are involved?

  1. <script>Loads the Javascript
  2. <link>Load the CSS
  3. <img>Loading pictures
  4. <video><audio>Loading Multimedia
  5. <object><embed><applet>Load the plug-in
  6. <iframe>Load anything
  7. Links, jumps, form submissions

Which ones are not allowed?

  1. Cross-domain documents interact with each other using Javascript scripts with limited access to the API. For example, if an iframe comes from a different source than the parent page, it is not allowed to use Javascript to manipulate the parent page DOM
  2. Between different sourcesXMLHttpRequestNot allowed to

1. The modified source

The source of a page can be modified through document.domain, such as a page a.b.com embedded in iframec.b.com. In this case, you only need to set the document.domain of both pages to b.com.

2. Use a proxy

Cross domain is for the front end, the server is not cross domain this thing, so the background Settings, the front end access to a page of the same origin, and then the background requests the data to a different source of the page.

The front end

    var xhr = new XMLHttpRequest();
    var url = 'http://localhost:3000/api'; / / request to http://localhost:3000/api to get the data XHR. Open ('GET', url);
    xhr.send(null);
    xhr.onreadystatechange = () => {
        if(xhr.readyState === xmlHttprequest.done && xhr.status === 200) {// If the request is successful text.innerhtml = xhr.response; }}Copy the code

Domain server

    // nodeJs express
    var proxy = require('http-proxy-middleware');
    var app = express();
    app.use('/api', proxy({target: 'http://localhost:3001/', changeOrigin: true}));
Copy the code

3.JSONP

Since

The front end

  <script src="http://other.com/ajax.json?callback=myFunction"></script>
Copy the code

Cross-domain server

When the interface retrieves the callback, it passes the returned data to the callback as an argument and executes it.

  // nodeJs express
  app.get('/'.function (req, res) {
      var callbackName = req.query.callback;
      res.send(callbackName+"({'message': 'hello world'});");
  })
Copy the code

disadvantages

  1. There are security issues
  2. Can only be GET requests
  3. The invocation is asynchronous

4.Web Messaging

This is an interface of HTML5, using the postMessage method in the interface, mainly used to exchange data between two Windows, can not be used to exchange data with the server.

otherWindow.postMessage(message, targetOrigin, [transfer]);
Copy the code

OtherWindow is a reference to the receiver window. Generally, it is in the following ways:

  1. window.iframe[0]
  2. document.getElementByTagName(‘iframe’)[0].contentWindow
  3. The reference returned by window.open
  4. Event. source Indicates the source of the received data

While Message supports almost all forms of data, transfer can be omitted

Usage:

/ / parent page document. GetElementByTagName ('iframe')[0].contentWindow.postMessage({"age": 10},'http://localhost:8080'); // Listen for data to return window.adDeventListener ('message'.function(e){
  console.log(e)
});
Copy the code
// iframe
window.addEventListener('mesage'.function(e){
  if(e.origin ! = ='http://localhost:8081') {return;
  }
  console.log(e);
  e.souce.postMessage('hello world',e.origin)
})
Copy the code

5. Cross-domain resource sharing CORS

CORS needs to be supported by both the browser and the server. The key is the server. As long as the server implements the CORS interface, it can communicate across domains.

CORS classifies requests into two categories: simple and non-simple.

Conditions for non-simple requests:

  1. Request mode is “PUT”, “DELETE”
  2. Content-typeThe fields areapplication/json

A simple request

For simple requests, the browser adds an origin field in the header indicating the source (protocol + host + port) from which the request is sent. The server decides whether to approve the request or not based on this value. If Origin is not in the specified source, it returns a normal HTTP response, but if it does not contain access-Control-Allow-Origin, it knows that something has gone wrong and throws an error that is caught by the XMLHttpRequest onError callback.

This error cannot be identified by the status code, and may be 200

If the source is within the permitted range, the response is returned with several additional information fields.

Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
Copy the code
  1. Access-Control-Allow-OriginRequired field. If it is*To receive requests for any domain name.
  2. Access-Control-Allow-CredentialsOptional field. CORS requests do not contain cookies and HTTP information by default, iftrue, indicating that cookies can be included in the server license request. In addition to the server allowing requests with cookie and HTTP information, the client must also allow it
        var xhr = new XMLHttpRequest();
        xhr.withCredentials = true;
    Copy the code
  3. Access-Control-Expose-Headers: FooBarThis field is optional. When CORS requests,XMLHttpRequestThe object’sgetResponseHeader()The method only gets six basic fields:Cache-control, Content-language, Content-Type, Expires, Last-Modified, Pragma. If you want to get the other fields, you have to be inAccess-Control-Expose-HeadersSpecify inside. The above example specifies that,getResponseHeader('FooBar')You can return the value of the FooBar field.

The front end

    var xhr = new XMLHttpRequest();
    var url = 'http://localhost:3001';    // Port 3001 is requested to obtain data
    xhr.open('GET', url);                 // Establish a connection with port 3001
    xhr.send(null);                       // The data sent to port 3001 is empty
    xhr.onreadystatechange = (a)= > {     // Call this function when the request status changes
        if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {  // If the request succeedstext.innerHTML = xhr.response; }}Copy the code

Cross-domain server

    // nodeJs express
    var app = express();
    app.get('/', (req, res) => {
        res.set('Access-Control-Allow-Origin'.'http://localhost:3000'); // Set origin to allow cross-domain access to port 3000 (3001) res.send("Hello world");
    });
Copy the code

Non-simple request

Non-simple requests differ in that there is an HTTP query request, called a “preflight” request, before formal communication.

The front end

var url = 'http://localhost:3001';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custom-Header'.'value');
xhr.send();
Copy the code

The browser

When the browser realizes that this is a non-simple request, it automatically issues a precheck request.

OPTIONS /cors HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...
Copy the code

The pre-checked request is OPTIONS, indicating that the request is for questioning.

Cross-domain server

After receiving the pre-check Request, the server checks the Origin, Access-Control-request-method, and access-Control-request-headers fields to confirm that cross-domain requests are allowed, and then responds

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain
Copy the code

Access-control-allow-methods indicates all cross-domain request Methods supported by the server.

If the precheck request passes, each subsequent CORS request is treated as a simple request.

disadvantages

Non-simple requests, the first request will be sent twice

6.WebSocket

Websockets are not homologous bound, so there is no cross-domain thing.

Basic usage:

var ws = new WebSocket("wss://echo.websocket.org");

ws.onopen = function(evt) {
  console.log("Connection open ...");
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
  ws.close();
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
}; 
Copy the code