JavaScript two cross domain technology comprehensive introduction

  • 2020-03-30 02:37:48
  • OfStack

This policy imposes important restrictions on the content of the page that JavaScript code can access, meaning that JavaScript can only access content in the same domain as the document that contains it.

JavaScript is a security policy that is particularly important in multi-iframe or multi-window programming, and in Ajax programming. According to this policy, pages under baidu.com contain JavaScript code that cannot access the content of pages under the google.com domain name. Even pages between different subdomains cannot be accessed by JavaScript code. The impact on Ajax is that Ajax requests implemented through XMLHttpRequest cannot submit requests to different domains, for example, pages under abc.example.com, cannot submit Ajax requests to def.example.com, and so on.

However, the "same origin policy" is too demanding when doing some in-depth front-end programming that inevitably requires cross-domain operations. This article Outlines some of the techniques required to cross domains on this issue.

Let's discuss cross-domain technologies in two ways: first cross-domain technologies with different subdomains, and then cross-domain technologies with completely different domains.

(I) cross-domain technology of different subdomains.

Let's discuss two issues: the first is how to make JavaScript calls across different subdomains; The second problem is how to submit Ajax requests to different subdomains.

To solve the first problem, assume that there are two different subdomains under the example.com domain: abc.example.com and def.example.com. Now suppose there is a page under def.example.com that defines a JavaScript function:

function funcInDef() {
    .....
}

We want to call the above function on a page under abc.example.com. Let's also assume that the page below abc.example.com we're talking about is embedded in the page below def.example.com as an iframe, so we might try to make the following call inside the iframe:

window.top.funcInDef();

Okay, notice that this call is prohibited by the "same origin policy" described earlier, and the JavaScript engine throws an exception directly.
To implement the above call, we can do this by modifying the domain property of the two pages. For example, we can add the following JavaScript snippet to the top of the two pages above under abc.example.com and def.example.com:
document.domain = "example.com";

In this way, the two pages are in the same domain and the previous call can execute normally.

The important thing to note here is that the document.domain property of a page can only be set to a higher level domain (other than a first level domain), but not to a subdomain deeper than the current domain. For example, the abc.example.com page can only set its domain to example.com, not sub.abc.example.com, and certainly not to the top-level domain com.

The above example discusses the case where two pages are part of an iframe nesting relationship, and the principle is exactly the same when two pages are open versus opened.

Now let's tackle the second problem: how to submit Ajax requests to different subdomains.
Typically, we create an XMLHttpRequest object with code similar to the following:

factories = [function() {
    return new XMLHttpRequest();
},
function() {
    return new ActiveXObject("Msxml2.XMLHTTP");
},
function() {
    return new ActiveXObject("Microsoft.XMLHTTP");
}];
function newRequest() {
    for (var i = 0; i & lt; factories.length; i++) {
        try {
            var factory = factories[i];
            return factory();
        } catch(e) {}
    }
    return null;
}

The code above refers to ActiveXObject for compatibility with the IE6 family of browsers. Each time we call the newRequest function, we get an Ajax object that we just created, and we use that Ajax object to send the HTTP request. For example, the following code sends a GET request to abc.example.com:

var request = newRequest();
request.open("GET", "http://abc.example.com" );
request.send(null);

Assuming that the above code is contained in a page under the abc.example.com domain name, the GET request can be sent successfully without any problems. However, if you now want to send a request to def.example.com, a cross-domain problem occurs and the JavaScript engine throws an exception.
The solution is to place a cross-domain file under the def.example.com domain, let's say crossdomain.html; Then move the previous definition of the newRequest function to this cross-domain file; Finally, as we did before when we modified the document.domain value, we added:
The same code at the page code block index 2

To use the cross-domain file, we embedded a hidden iframe pointing to the cross-domain file in the Ajax page of the abc.example.com domain invocation, for example:

<iframe name="xd_iframe" style="display:none" src="http://def.example.com/crossdomain.html">
</iframe>


At this time, the page under the abc.example.com domain and the cross-domain file crossdomain. HTML are under the same domain (example.com), we can call the newRequest function in crossdomain. HTML in the page under the abc.example.com domain:
var request = window.frames["xd_iframe"].newRequest();

The resulting request object is then ready to send an HTTP request to http://def.example.com.

(ii) cross-domain technology of completely different domains.

If the top-level domains are all different, for example, example1.com and example2.com want to communicate on the front end through JavaScript, the technology required is more complex.

Before going into cross-domain techniques for different domains, let's make it clear that the same techniques that we're going to talk about apply to the previous case for different subdomains, because cross-domain is just a special case of cross-domain problems. Of course, using the right technology under the right conditions can guarantee better efficiency and greater stability.

In short, according to different cross-domain requirements, cross-domain technologies can be grouped into the following categories:
1. JSONP cross-domain GET request
2. Implement cross-domain through iframe
3. Flash cross-domain HTTP requests
4, window. PostMessage
The various techniques are described in detail below.
1. The json.
Use create in the page < Script> Methods of nodes that submit HTTP requests to different domains are called JSONP, and this technique solves the problem of submitting Ajax requests across domains. JSONP works as follows:
Suppose in http://example1.com/index.php this page submit a GET request to http://example2.com/getinfo.php, we can put the following JavaScript code on this page http://example1.com/index.php to achieve:

var eleScript= document.createElement("script");
eleScript.type = "text/javascript";
eleScript.src = "http://example2.com/getinfo.php";
document.getElementsByTagName("HEAD")[0].appendChild(eleScript);


<?xml version="1.0"?>
<cross-domain-policy>
    <allow-access-from domain="example2.com" />
</cross-domain-policy>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>CrossDomain</title>
</head>
<body>
    <iframe src="http://sh-tanzhenlin/CrossDomain-child.html"
        frameborder="0" visible="false" height="0" width="0" id="ifrChild"></iframe>

    <script type="text/javascript">
        var child = document.getElementById("ifrChild");
        var openerObject = {
                funcInParent:function(arg){
                    alert(arg);
                    alert('executed by a function in parent page');
                }
            }

        if(!+'v1' && !'1'[0]){ //test browser is ie6 or ie7   
            //crack
            child.contentWindow.opener = openerObject;
        }
        else{
            //postMessage showtime
        }

        function onClick(){
            //debugger;
            openerObject.funcInIframe('data from parent page ');
        }
    </script>
    <input type="button" value="click me" onclick="onClick()" />
</body>
</html>

Use iframe to embed pages under other fields:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
               <script type="text/javascript">
                        onload = function(){
                                if(!+'v1' && !'1'[0]){ // test browser if is ie6 or ie7
                                        window.opener.funcInIframe=function(arg){
                                                alert(arg);
                                                alert('executed by a function in iframe');
                                        }
                                        window.opener.funcInParent('data from iframe')
                                }
                        }
                </script>
        </head>
        <body>
        </body>
</html>


Related articles: