The first step is to understand where the cross-domain problems of browsers come from

The cross-domain problem is caused by the same origin policy, protocol, domain name, and port of the browser. If one of the three is inconsistent, the problem is cross-domain.

The browser’s same-origin policy: A script can only read properties of Windows and documents from the same source, which is a combination of host name, protocol, and port number.

URL address: www.baidu.com:80/index.html?… Protocol: // Domain name: port/resource path? Query string #hash

classification The basic content
agreement http,https,ftp
The host name localhost
port The default HTTP port is 80. The default HTTPS port is 443

The same origin policy causes problems:

Ajax requests under different domain names cannot be implemented.

Access to fetch at ‘xxx’ from origin ‘xxx’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

As follows:

There are six ways to solve cross-domain problems:

JSONP(JSON with Padding: JSON) is a new method to apply to JSON. JSON/JSONP – JSONP only supports GET requests, not POST requests (like adding a script tag to a page, using the SRC attribute to trigger the request to the specified address, so only get requests)

JSONP application tip: In HTML tags, some tags such as script, IMG and other tags that fetch resources have no cross-domain restrictions.

Header (‘ access-Control-allow-Origin :*’); Header (‘ access-Control-allow-method :POST,GET’); The way access is allowed

3. Nginx reverse proxy www.baidu.com/index.html…

Document. Domain is divided into two types: one is that XHR cannot access documents from different sources; the other is that different Windows cannot interact with each other. Document.domain mainly solves the second case, and can only be applied to the case of the same primary domain and different subdomains; The document.domain setting is limited. We can only set document.domain to its own parent or a higher parent, and the primary domain must be the same. Such as: The document.domain of a document in A.b.example.com can be set to any of a.b.example.com, b.example.com, or example.com. However, it cannot be set to c.A.b.example.com because it is a subdomain of the current domain. It cannot be set to baidu.com because the primary domain is different. Compatibility: supported by all browsers; Advantages: It can realize the mutual access and operation between different Windows. Disadvantages: Only applicable to communication between Windows, not XHR; It can be used only when the primary domains are the same and the subdomains are different. How to use it: Different frameworks can get the Window object, but not the corresponding properties and methods. For example, there is a page with the address www.example.com/a.html, and on this page… Obviously, the page is in a different domain from the iframe framework inside it, so we cannot get the contents of the iframe by writing JS code in the page. Sample code:

<script>
function test(){
	var iframe = document.getElementById(' ifame');
	var win = document.contentWindow;// The window object in the iframe can be retrieved, but its properties and methods are almost unavailable
	var doc = win.document;// The document object in the iframe is not available
	var name = win.name;// The name attribute of the window object is not available
}
</script>
<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
Copy the code

At this point, document.domain can come in handy, we just need to www.example.com/a.html and example.com/b.html pages… 1. Set document.domain in www.example.com/a.html:

<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
<script type="text/javascript">
    document.domain = 'example.com';// set to primary
    function test(){
        alert(document.getElementById('the  iframe').contentWindow);//contentWindow Gets the window object of the child window
    }
</script>
Copy the code

2. In example.com/b.html, set d… :

<script type="text/javascript">
    document.domain = 'example.com';// Load the page in iframe and set document.domain to be the same as document.domain on the main page
</script>
Copy the code

5. Window.name Key point: window.name shares a window.name during the page life cycle; Compatibility: supported by all browsers; Advantages: The simplest use of browser features to achieve data transfer between different domains; No special configuration of the front and back ends is required; Disadvantages: Size limitation: window.name maximum size is about 2M, different browsers may have different conventions; Security: the current page all Windows can be modified, very insecure; Data type: The data passed can only be a string, if it is an object or other automatically converted to a string. How to use: Change the value of window.name.

6. PostMessage key points: postMessage is a new concept introduced by H5, and now it is being further promoted and developed. It carries out a series of encapsulation, which can be used in the way of window.postMessage and can listen to the messages sent by it. Compatibility: mobile terminal can be safely used, but PC terminal needs to do degradation processing advantages: no back-end intervention can do cross-domain, a function plus two parameters (request URL, send data) can be done; Good mobile compatibility; Disadvantages: One-to-one transmission mode cannot be achieved: many messages need to be identified in monitoring. Since messages sent by postMessage are equivalent to a broadcast process for different functions of the same page, all onMessages on the page will be received, so messages need to be judged. Security issues: Three parties can intercept, inject HTML or script to listen to messages, so that the effect of tampering can be achieved. Therefore, postMessage and onMessage must be restricted in this aspect. The sent data will be serialized through a structured clone algorithm, so only parameters that meet the requirements of the algorithm can be parsed; otherwise, an error will be reported. For example, function cannot be passed as a parameter. Usage: communication function, sendMessage is responsible for sending messages, bindEvent is responsible for message monitoring and processing, you can do a general understanding through the code; Sample code:

Storage.prototype.sendMessage_=function(type,params,fn){
   if(this.topWindow){
       this.handleCookie_(type,params,fn);
       return;
   }
   var eventId = this.addToQueue_(fn,type);
   var storageIframe = document.getElementById('mip-storage-iframe');
   var element = document.createElement("a");
   element.href = this.origin;
   var origin = element.href.slice(0,element.href.indexOf(element.pathname)+1);
   storageIframe.contentWindow.postMessage({
       type:type,
       params:params,
       eventId:eventId
   },origin);
}
Storage.prototype.bindEvent_=function(){
   window.onmessage = function(res){
       // Determine the source
       if(window == res.source.window.parent &&
           res.data.type === this.messageType.RES &&
           window.location.href.match(res.origin.host).length >0) {var fn = this.eventQueue[res.data.eventId];
           fn && fn();
           delete this.eventQueue[res.data.eventId];
           var isEmpty = true;
           for(var t in this.eventQueue){
               isEmpty = false;
           }
           if(isEmpty){
               this.id = 0;
           }
       }
   }.bind(this);
}
Copy the code