What is cross-domain? -> Soul problem!!

Cross-domain is when a document or script in one domain tries to request resources in another domain.


Typing and highlighting

1. The first must be communication between the two domains

2. The key word to remember is script

On a recent project, I made a public backend shell (multiple backend/domain names), and a beautiful girl on my team found a problem while doing it:

Requesting the same interface under this domain name is ok in this project, whereas requesting the same interface in this shell has no accessCopy the code

An example figure is shown below

Here we can see common.js under b.com loaded by a.com

False is then returned by api.com via common.js request

So using scripts in one domain to request resources in another domain is also cross-domain

Cross-domain is typically a class of request scenarios that are limited by the browser’s same-origin policy

At this point, it is necessary to mention the broad cross-domain and same-origin policies


Generalized cross-domain

<link>, <script>, <img>, <frame> and other DOM tags, as well as background: URL (), @font-face() and other file external links. Js-initiated Ajax requests, DOM and JS object cross-domain operations, etcCopy the code

The same-origin policy

Meaning:

The Cookie set on webpage A cannot be opened on webpage B unless the two pages are “homologous”.

Objective:

In order to ensure user information security, prevent malicious sites to steal data

The same origin policy refers to three that are the same:
  • The agreement is the same
  • Domain name is the same
  • The same port
Limit range of the same-origin policy
  • Cookie, LocalStorage, and IndexDB cannot be obtained
  • DOM not available
  • AJAX requests cannot be sent

How to break through cross domain

  1. Cross domains via JSONP
  2. The iframe cross-domain
  3. PostMessage cross-domain
  4. CORS cross-domain
  5. Nginx agents cross domains
  6. Nodejs middleware proxies cross domains
  7. Cross domain using WebSocket

First, cross domains through JSONP

The essence of JSONP cross-domain is to achieve cross-domain communication by dynamically creating a script and then requesting a url with parameters.

  1. An example of the native implementation is as follows:
<script>
var src = "https://xxx.com/xxx.php?a=jsonpTest&callback=onback";

var script = document.createElement("script");
script.type = 'type/javascript'; script.src = src; document.head.appendChild(script); // Define the callback functionfunction onBack(res) {
    console.log(res);
}
<script>
Copy the code

The server returns:

onBack({state: true})
Copy the code
  1. Jquery Ajax:
$.ajax({
    url: 'https://xxx.com/xxx.php'.type: 'get',
    dataType: 'jsonp'JsonpCallback:"onBack"Data: {a: jsonpTest}, success:function() { console.log(res); }});Copy the code

The methods of other frameworks are consistent and can be adjusted according to different request modules

Examples of back-end PHP code:

<? php$callback = $_GET['callback'];
if (empty($callback)) {
    echo json_encode([
        state => false,
        errMsg => "Incorrect request"
    ]);
    return;
}
$data = json_encode([
    state => true,
    errMsg => ""
]);

echo "{$callback} ({$data})";
Copy the code

Iframe is cross-domain

1. Document. domain + iframe cross-domain

This parameter is valid only when the primary domains are the same and the subdomains are differentCopy the code

Implementation principle: two pages through JS forced document.domain as the base of the primary domain, also to achieve the same domain.

1.) Parent page (n.xxx.com/a.html)

<iframe id="iframe" src="http://m.xxx.com/b.html"></iframe>
<script>
    document.domain = 'xxx.com';
    var user = 'admin';
</script>
Copy the code

2.) Sub-page (m.xxx.com/b.html)

<script>
    document.domain = 'xxx.com'; // Get console.log(window.parent-user); </script>Copy the code

2. Location. hash + iframe cross-domain

Implementation principle: increase the middle page to achieve. Three pages, different fields use iframe location.hash to transfer values, the same fields directly js communication.

Concrete implementation is shown as follows:

The main method onhashchange

Code implementation:

  1. a.html
<iframe id="iframe" src="http://www.b.com/b.html" style="display:none;"></iframe>
<script>
    var iframe = document.getElementById('iframe'); / / to the b.h HTMLhashvaluesetTimeout(function() {
        iframe.src = iframe.src + '#user=admin'; }, 1000); // callback methods open to homologous C.HTMLfunction onCallback(res) {
        console.log(res);
    }
</script>
Copy the code
  1. b.html
<iframe id="iframe" src="http://www.a.com/c.html" style="display:none;"></iframe>
<script>
    var iframe = document.getElementById('iframe'); // listen for a.htmlhashValue, which is passed to C.html window.onhashchange =function () {
        iframe.src = iframe.src + location.hash;
    };
</script>
Copy the code
  1. c.html
<script> // Listen for b.HTML incominghashValue window. Onhashchange =function() {/ / by manipulating the sympatric a.h HTML js callback, the results back to the window. The parent, the parent. OnCallback ('hello: ' + location.hash.replace('#user='.' '));
    };
</script>
Copy the code

3. Window. name + iframe cross domains

The properties of the window.name attribute:

  • The name value persists after different pages (and even different domain names) are loaded
  • Supports very long name values (2MB)

1) a.h HTML

<script>
var proxy = function(url, callback) {
    var state = 0;
    var iframe = document.createElement("iframe");
    iframe.src = url;
    
    iframe.onload = function() {
        if(state = = = 0) {/ / for the first time after the success of the onload Switch to the agent page iframe. ContentWindow. Location ='http://xxx.com/proxy.html';
            state = 1;
        } else if(state === 1) {// The second onload succeeds and the iframe is destroyed // 1. Release the memory / / 2. Ensure that will not be other domain frame js access callback (iframe. ContentWindow. Name); destoryFrame(); } } document.body.appendChild(iframe); // Destroy the iframefunction destoryFrame() {
        iframe.contentWindow.document.write(' '); iframe.contentWindow.close(); document.body.removeChild(iframe); }} // request cross-domain B page data proxy('http://yyy.com/b.html'.function(data){
    console.log(data);
});


</script>
Copy the code

2) b.h HTML

<script>
    window.name = 'Fill in the cross-domain data here';
</script>
Copy the code

3) proxy. HTML proxy page, the same domain as A.html, the content is empty.

When the SRC attribute of the iframe is passed from another domain to the local domain, cross-domain data is passed from the window.name of the iframe to the local domain.

A wave of operation 666 perfectly circumvented the browser’s cross-domain access restrictions, but at the same time was a secure operation.

I have seen relevant operations in Ali Cloud

3. PostMessage cross-domain

PostMessage is an API in HTML5 Level2 that can be used to solve the following problems:

  • Page and the new window that the page opens
  • Message passing between multiple Windows
  • Message passing between pages and nested iframes

postMessage(data, origin)

data:

The HTML5 specification supports any primitive type or copiable object, but some browsers only support strings, so it’s best to serialize the argument with json.stringify ().

origin:

Protocol + host + port number can also be set to “*”, which indicates that the message can be sent to any window. If you want to specify the same source as the current window, set this parameter to “/”.

The following is an example:

a.html

<iframe id="iframe" src="http://yyy.com/b.html" style="display:none;"></iframe>
<script>       
    var iframe = document.getElementById('iframe');
    iframe.onload = function() {
        var data = {
            name: 'I'm XXX'}; / / send cross domain data to yyy.com iframe. ContentWindow. PostMessage (JSON. Stringify (data),'http://yyy.com'); }; // Accept data from YYY.com'message'.function(e) {
        console.log(e.data);
    }, false);
</script>
Copy the code

b.html

<script> // Receive xxx.com data window.addeventListener ('message'.function(e) {
        console.log(e.data);

        var data = JSON.parse(e.data);
        if (data) {
            data.name2 = "I am yyyy"; / / processing and then back to the xxx.com window. The parent. PostMessage (JSON. Stringify (data),'http://xxx.com'); }},false);
</script>
Copy the code

4. CORS is cross-domain

For common cross-domain requests, only access-Control-allow-origin is required on the server. This parameter is not required on the front end. If cookie is required, access-Control-allow-origin is required on both the front and back ends.

Note: Due to the restriction of the same-origin policy, the cookie read is the cookie of the domain of the cross-domain request interface, not the current page.

All browsers support this functionality (IE8+ : IE8/9 requires the XDomainRequest object to support CORS) and CORS has become a common cross-domain solution.

1. Perform front-end Settings

// With cookie xhr.withcredentials =true;
Copy the code

2. Configure the server

Set the header head

(Protocol + domain name + port) // If there is no port, do not add the end of the port'/'Access-control-allow-origin * // Allows authentication cookies on the front end. // After this function is enabled, the wildcards cannot be used and the access-Control-allow-credentials must be specifiedtrueAccess-control-allow-headers content-type, x-requested-withCopy the code

Nginx proxies cross domains

1) A type of CORS

Example:

location / {
  add_header Access-Control-Allow-Origin *;
}
Copy the code

Other configurations are similar to those of CORS

2) Reverse proxy interface Through nginx configure a proxy server as a jumper, reverse proxy access interface, and modify the cookie in the domain information, convenient cookie writing in the current domain, to achieve cross-domain login.

This wave operation is working, Iron

Nodejs middleware proxy across domains

The rewrite parameter can also be set to rewrite the domain name of the cookie in the response header.

Seven, use WebSocket cross domain

WebSocket is a new H5 protocol that implements full-duplex communication between browsers and servers, while allowing cross-domain communication.

We usually use socket. IO to simplify operations;

Simply set up the WS/WSS link