0. Cross-domain: JavaScript is not allowed to invoke objects of other pages across domains for security reasons. But the security restrictions also bring a lot of trouble to inject IFRAME or AJAX applications.
1. First what is cross-domain, simple to understand is because of the JavaScript homologous policy limitations, a.com domain name JS can not operate B.Com or c.a.com under the domain name of the object.
A more detailed explanation can be seen in the following table:
URL |
Description |
whether to allow communication |
Http://www.a.com/a.js Http://www.a.com/b.js |
Under the same domain name |
Allow |
Http://www.a.com/lab/a.js Http://www.a.com/script/b.js |
Different folders under the same domain name |
Allow |
Http://www.a.com:8000/a.js Http://www.a.com/b.js |
Same domain name, different ports |
Not allowed |
Http://www.a.com/a.js Https://www.a.com/b.js |
Same domain name, different protocols |
Not allowed |
Http://www.a.com/a.js Http://70.32.92.74/b.js |
Domain and domain name corresponding IP |
Not allowed |
Http://www.a.com/a.js Http://script.a.com/b.js |
Primary domain is the same, subdomain is different |
Not allowed |
Http://www.a.com/a.js Http://a.com/b.js |
Same domain name, different level two domain name (IBID.) |
Not allowed (cookies are also not allowed in this case) |
Http://www.cnblogs.com/a.js Http://www.a.com/b.js |
Different domain names |
Not allowed |
-
Pay special attention to two points:
First, if it is the protocol and the port caused by the cross-domain problem "foreground" is powerless;
Second: On a cross-domain issue, the domain is only identified by the "header of the URL" and does not attempt to determine whether the same IP address corresponds to two domains or two domains on the same IP.
The "header of the url" refers to Window.location.protocol +window.location.host, which can also be understood as "Domains, protocols and ports must match".
2. Cross-Domain solutions:
1, the Document.domain+iframe setting
For examples where the primary domain is the same and the subdomain is different, it can be resolved by setting the Document.domain method.
For example, http://www. a.com/a.html and/HTTP. a.com/b.html.
1) At this time you can add document.domain = ' a.com 'in two files respectively;
2) then through the a.html file to create an IFRAME, to control the contentdocument of the IFRAME, so that two JS files can be "interactive".
Of course, this approach can only solve the same primary domain and the two-level domain name is different , if you whimsical script.a.com Domian set to Alibaba.com that obviously will be error! The code is as follows:
The a.html on the www.a.com
Document.domain = ' a.com '; var ifr = document.createelement (' iframe '= ' http://script.a.com/b.html '= ' None ' function () { var doc = Ifr.contentdocument | | ifr.contentWindow.document; // manipulating the b.html here. Alert (Doc.getelementsbytagname ("H1") [0].childnodes[0].nodevalue);};
The b.html on the script.a.com
Document.domain = ' a.com ';
Note: The domain default for a page is equal to Window.location.hostname.
The primary domain is a domain name without www, such as a.com, which is usually preceded by a two-level domain name or a multilevel domain name, such as Www.a.com, which is actually a two-level domain name.
Domain can only be set as the primary domain name, and domain can not be set to c.a.com in B.a.com.
- Problem:
1, security, when one site (b.a.com) is attacked, another site (c.a.com) can cause security vulnerabilities.
2, if a page to introduce multiple IFRAME, to be able to operate all the IFRAME, you must set the same domain.
2. Dynamically Create Script---jsonp (json+padding)
Although the browser prohibits cross-domain access by default, it does not prohibit referencing other domain's JS files in the page , and can freely execute the function in the introduced JS file (including manipulating cookies, DOM, etc.).
According to this, you can It is convenient to create a script node to achieve complete cross-domain communication. (Specific practice can refer to Yui's get Utility)
It's pretty interesting to judge that the script node is loaded: IE can only pass the script's ReadyStateChange property, and the other browser is the Load event for the script. Here are some ways to determine the completion of script loading.
function () { if (! This is this. readyState = = = ' complete ') { // callback is executed here null; }};
Specific methods:
var script = document.createelement (' script '); = "Http://aa.xx.com/js/*.js"; Document.body.appendChild (script);
By dynamically creating the script tag can load the other domain's JS file, and then through this page can invoke the load after the JS file function, the flaw is that can not load other domain documents, can only be JS file.
Jsonp is done this way, jsonp by passinga callback parameter to the other domain, wrapping the callback parameter value and the JSON string as a JavaScript function through the background of the other domain, as it is emitted through the script tag
the request, The browser will parse the returned string according to JavaScript, implementing the data transfer between domain and domain.
The support for JSONP in jquery is also based on this scenario.
3. Using IFRAME and Location.hash
This method is more round, but it can solve the problem of footstep replacement in the case of complete cross-domain. The principle is to use Location.hash to transmit values.
In the Url:http://a.com#helloword ' #helloworld ' is location.hash, changing the hash does not cause the page to refresh, so you can use the hash value for data transfer, of course, the data capacity is limited.
Assume that the file under the domain name a.com cs1.html to and cnblogs.com the cs2.html of the domain name to pass the information.
Cs1.html first create automatically create a hidden iframe,iframe src point cnblogs.com the cs2.html page under the domain name, when the hash value can be used for parameter transfer. cs2.html response please
after the request will be modified cs1.html hash value to pass the data ( because two pages are not in the same domain IE, chrome is not allowed to modify the value of Parent.location.hash, so the use of a proxy under the A.com domain name
Iframe;firefox can be modified). At the same time, add a timer on the cs1.html, interval time to determine whether the value of Location.hash has changed, a little change gets the hash value. the code is as follows:
A.com file cs1.html file:
functionstartrequest () {varIFR = document.createelement (' iframe '); Ifr.style.display= ' None '; IFR.SRC= ' Http://www.cnblogs.com/lab/cscript/cs2.html#paramdo '; Document.body.appendChild (IFR);}functionCheckHash () {Try { vardata = Location.hash? Location.hash.substring (1): "; if(Console.log) {Console.log (' Now the data is ' +data); } } Catch(e) {};} SetInterval (CheckHash,2000);
Cs2.html under the cnblogs.com domain name:
//simulates a simple parameter handling operationSwitch(location.hash) { Case' #paramdo ': CallBack (); Break; Case' #paramset ': //Do something ... Break;}functionCallBack () {Try{Parent.location.hash= ' Somedata '; } Catch(e) {//ie, chrome security mechanism can not modify the Parent.location.hash, //so we're going to use a proxy iframe in the middle of the cnblogs domain. varIfrproxy = document.createelement (' iframe '); Ifrproxy.style.display= ' None '; IFRPROXY.SRC= ' Http://a.com/test/cscript/cs3.html#somedata ';//Note that the file is under the "a.com" fieldDocument.body.appendChild (Ifrproxy); }}
The domain name under a.com cs3.html
Because Parent.parent and itself belong to the same domain, they can change the value of their location.hash Parent.parent.location.hash = self.location.hash.substring (1);
Of course, there are many shortcomings, such as data directly exposed to the URL, data capacity and type are limited, etc...
4, Window.name realization of cross-domain data transfer
Please refer to: Window.name for cross-domain data transfer.
5. Use HTML5 postMessage
One of the coolest new features in HTML5 is the cross-document messaging Messaging. Next-generation browsers will support this feature: Chrome 2.0+, Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, and Safari 4.0+. Facebook has used this feature to support web-based real-time messaging with PostMessage.
-
otherwindow.postmessage (message, targetorigin); Otherwindow: A reference to the window that receives the information page can be the Contentwindow attribute of the IFRAME in the page, the return value of the window.open, and the value taken from Window.frames by name or subscript; message: The data to be sent, string type;targetorigin: Used to limit Otherwindow, "*" means no restrictions
Code in a.com/index.html:
<iframe id= "IFR" src= "b.com/index.html" ></iframe><script type= "Text/javascript" > function() { var ifr = document.getElementById (' IFR '); var targetorigin = ' http://b.com '; // if it's written as ' http://b.com/c/proxy.html ' effect // If you write ' http://c.com ', you won't execute postmessage. Ifr.contentWindow.postMessage (' I was there! ' , targetorigin);}; </script>
Code in b.com/index.html:
<script type= "Text/javascript" > Window.addeventlistener ( ' message ', // popup "I was there!" alert (Event.source); // reference to the Window object in A.com, index.html // ); </script>
6. Using Flash
This is the method seen from the IO component of YUI3, specifically visible http://developer.yahoo.com/yui/3/io/. You can see more of the cross-domain proxy file specification in Adobe Developer connection: Ross-domain Policy, "File specifications," HTTP Headers blacklist.7. Using the window Clipboard
The cross-domain problem of JS