In client-side programming languages, such as JavaScript and ActionScript, the same-origin strategy is an important security concept that has important implications for securing data. The same-origin policy stipulates that scripts across domains are isolated, and one domain script cannot access and manipulate most of the properties and methods of another domain. So what is the same domain and what is a different domain?
Homologous policy
In client-side programming languages, such as JavaScript and ActionScript, the same-origin strategy is an important security concept that has important implications for securing data. The same-origin policy stipulates that scripts across domains are isolated, and one domain script cannot access and manipulate most of the properties and methods of another domain. So what is the same domain and what is a different domain? When two domains have the same protocol (such as HTTP), the same ports (such as 80), the same host (for example), then we can think of them as the same domain. For example, and is the same domain, and,,, any two of them will form a cross-domain. The same-origin policy should also handle special cases, such as restricting access to scripts under the file protocol. The local HTML file in the browser is opened through the file protocol, if the script can be accessed through the file protocol to any other files on the hard disk, there will be a security risk, the current IE8 still have such a hidden danger.
Cross-domain resource sharing is constrained by the same-origin policy. But with the practice of people and the progress of the browser, there are many valuable experiences in the cross-domain request of the skills of precipitation and accumulation. Here I divide the cross-domain resource sharing into two types, one-way data request, and the other is two-way message communication. Next I'll list some common cross-domain approaches, and the source code for the following cross-domain instances can be obtained from here.
What is a 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. Here are some simple things to sort out about cross-domain issues:
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 |
do not allow |
http://www.a.com/a.js https://www.a.com/b.js |
same domain name, different protocol |
does not allow |
http://www.a. Com/a.js http://70.32.92.74/b.js |
domain name and domain name corresponding IP |
do not allow |
http://www.a.com/a.js H Ttp://script.a.com/b.js |
primary domain, subdomain 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 not allowed in this case) |
http://www.cnblogs.com/a.js H Ttp://www.a.com/b.js |
different domain names |
not allowed |
-
Pay special attention to two points:
-
First, if it is a cross-domain problem caused by protocol and port "front desk" 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".
Then briefly summarize in the "front desk" generally handle cross-domain approach, background Proxy This scenario involves the background configuration, here is not elaborated, interested can see Yahoo this article: "Javascript:use a Web Proxy for Cross-domain XMLHttpRequest Calls "
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. Specifically, the http://www.a.com/a.html and http://script.a.com/b.html two files can be added document.domain = ' a.com ' And then create an IFRAME in the a.html file to control the contentdocument of the IFRAME so that the two JS files can "interact" with each other. 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 '); ifr.src = ' http://script.a.com/b.html '; Ifr.style.display = ' None ';d ocument.body.appendChild (IFR); ifr.onload = function () { var doc = Ifr.contentdocument | | ifr.contentWindow.document; Manipulate b.html alert here (Doc.getelementsbytagname ("H1") [0].childnodes[0].nodevalue];
The b.html on the script.a.com
Document.domain = ' a.com ';
This approach applies to any page in {www.kuqin.com, kuqin.com, script.kuqin.com, css.kuqin.com} to communicate with each other.
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. Create script dynamically
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.). Based on this, 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.
Js.onload = Js.onreadystatechange = function () { if (!this.readystate | | this.readystate = = = ' Loaded ' | | this.readysta Te = = = ' complete ') { //callback is executed here js.onload = Js.onreadystatechange = null;} };
3. Using IFRAME and Location.hash
Between different domains, JavaScript can only do very limited access and operation, in fact, we use these limited access rights to achieve cross-domain communication purposes. FIM (Fragment identitier Messaging) was invented on this premise. The parent window can read and write URLs to the IFRAME, and the IFRAME can read and write to the parent window's Url,url part is called Frag, which is the # number and the character behind it, which is generally used for browser anchor positioning, and the server side does not care about this part, It should be said that the HTTP request does not carry frag, so this part of the modification will not produce an HTTP request, but will produce a browser history. The principle of FIM is to change the frag part of the URL for two-way communication. Each window sends a message by changing the location of the other window, and receives the message by listening for changes to its own URL. This way of communication will cause some unnecessary browser history, and some browsers do not support Onhashchange event, need polling to know the URL changes, finally, the URL in the browser has a length limit, which restricts the amount of data transferred each time.
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. Assuming that the file under the domain name a.com cs1.html to and cnblogs.com the cs2.html of the domain name, cs1.html first creates a hidden iframe,iframe that automatically creates a cnblogs.com page under the cs2.html domain name The ash value can be used for parameter passing. The cs2.html responds to the request and then passes the data by modifying the hash value of the cs1.html ( because two pages are not in the same domain ie, Chrome does not allow you to modify the value of Parent.location.hash, so you can modify it by using an agent Iframe;firefox under the a.com domain name. 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:
First the file cs1.html file under a.com:
function Startrequest () { var IFR = document.createelement (' iframe '); Ifr.style.display = ' None '; IFR.SRC = ' Http://www.cnblogs.com/lab/cscript/cs2.html#paramdo '; Document.body.appendChild (IFR);} function CheckHash () { try { var data = 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 operation switch (location.hash) {case ' #paramdo ': callBack (); break; Case ' #paramset ': //do something ... break;} function CallBack () { try { parent.location.hash = ' somedata '; } catch (e) { //IE, Chrome's security mechanism cannot modify the Parent.location.hash, //So to take advantage of an intermediary cnblogs domain under the proxy iframe var ifrproxy = 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" field document.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
Access control is more than a cross-domain approach and is currently supported in only a few browsers that can send a cross-domain HTTP request (Firefox, Google chrome, etc. via XMLHttpRequest, IE8 is implemented by Xdomainrequest), the requested response must contain a Access-control-allow-origin HTTP response header that declares the accessibility of the requesting domain. For example, the asset.php sends a cross-domain HTTP request, then asset.php must include the following response header:
Header ("Access-control-allow-origin:"); window.name
The Name property of the Window object is a very special property, and when the window's location changes and then reloads, its Name property can remain unchanged. Then we can load the other domain's page B with an IFRAME in page A, While Page B uses JavaScript to assign the data to be passed to Window.name,iframe after loading, page a modifies the address of the IFRAME, changes it to an address in the same domain, and then reads out the value of the window.name. This approach is ideal for one-way data requests, and the protocol is simple and secure. External scripts are not executed as JSONP.
Articles longer listed here are not easy to read, see the window.name implementation of 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. This can be the Contentwindow property of the IFrame in the page, the return value of the window.open, or the value taken from the 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" >window.onload = function () { var IFR = document.getElementById (' IFR '); var targetorigin = ' http://b.com '; //If written as ' http://b.com/c/proxy.html ' effect //If written ' http://c.com ' will not execute postMessage ifr.contentWindow.postMessage (' I was there! ', targetorigin);}; </script>
Code in b.com/index.html:
<script type= "Text/javascript" > window.addeventlistener (' message ', function (event) { // Use the Origin property to determine the message source address if (event.origin = = ' http://a.com ') { alert (event.data); Eject "I was there!" alert (event.source); A reference to the Window object in A.com, index.html //But because of the same Origin policy, here Event.source cannot access the window object } , False);</script>
Reference article: Master HTML5 Programming Fifth-cross-document messaging mechanism, Https://developer.mozilla.org/en/dom/window.postmessage
6. Using Flash
Flash URLLoader
Flash has its own set of security policies that can be used by the server to declare which domain SWF files can be accessed by the Crossdomain.xml file, and SWF can also use the API to determine which domain SWF it can load. When accessing resources across domains, such as data from a domain request domain, we can use Flash to send HTTP requests. First, modify the crossdomain.xml on the domain (typically stored in the root directory if you do not need to create it manually) and add the whitelist. Second, send HTTP requests via Flash Urlloader, and finally pass the response results to JavaScript via the Flash API. Flash Urlloader is a common cross-domain solution, but if you need to support iOS, there's nothing you can do about it.
Flash LocalConnection
Two-way communication on the page can also be resolved by Flash, which has the LocalConnection class in the Flash API that allows two SWF to communicate through the process, where the SWF can be played in a standalone Flash player or air. It can also be embedded in an HTML page or in a PDF. Following this communication principle, we can nest a SWF in different domain HTML pages to achieve the purpose of passing data to each other. SWF Exchange data through LocalConnection is very fast, but each time the amount of data has a size limit of 40kb. In this way to cross-domain communication is too complex, and requires 2 SWF files, the practicality is not strong.
7, JSONP
JSONP (JSON with Padding) is a simple and efficient cross-domain approach where script tags in HTML can load and execute JavaScript from other domains, so we can dynamically load resources from other domains with the script tag. For example, I want to load domain B's data from page PageA of Domain A, then in the page pageb of domain B I declare the data required PageA in JavaScript, and then load the PageB in PageA with the script tag. Then the script in the PAGEB will be executed. Jsonp adds a callback function on this basis, PAGEB executes the function defined in PageA after loading, and the required data is passed to the function as an argument. JSONP is easy to implement, but there are some security implications, and if a third-party script executes arbitrarily, it can tamper with the page content and intercept sensitive data. But Jsonp is the right choice for passing data on both sides of a trusted side.
8. Server Proxy
When the data provider does not provide support for the JSONP protocol or the Window.name protocol, and there is no open access to other domains, we can crawl the data through the server proxy. For example, when a page under a domain requires a resource file Asset.txt under request, sending a direct AJAX request to/asset.txt is definitely blocked by the browser. At this point, we are under a proxy, and then bind the AJAX request to this proxy path, such as/proxy/, and then this agent sends HTTP request access under the Asset.txt, cross-domain HTTP requests are on the server side, the client does not produce cross-domain AJAX requests. This cross-domain approach does not require an agreement with the target resource and is aggressive, and it is also important to note that the agent should be protected in practice, such as restricting the use or frequency of use by others.
9. Cross Frame
Cross Frame is a variant of FIM that uses a blank iframe, does not generate redundant browser history, and does not require a change in the polling URL, making a big difference in usability and performance. The rationale for this is roughly the assumption that there is a page a.html on the domain and a blank proxy page proxya.html, There is a page b.html and a blank proxy page on the other domain proxyb.html,a.html when a message needs to be sent to b.html, the page creates a hidden iframe, The src of the iframe points to proxyb.html and the message as a URL frag, because b.html and proxyb.html are the same domain, so after the IFRAME loading is complete, b.html can obtain the URL of the IFRAME and then parse out Message, and remove the IFRAME. The same principle occurs when b.html needs to send a message to a.html. Cross frame is a good way to communicate in two directions, and it is safe and efficient, but it is not available in opera, but in opera we can use a simpler window.postmessage instead.
Summarize
There are many ways to cross-domain, and we can find the most suitable solution for different application scenarios. For example, one-way data request, we should prefer JSONP or window.name, two-way communication we take the cross Frame, we can also use the server proxy to crawl the data without a communication agreement with the data provider.
Common page constraints between different domains DOM elements include:
Window.location can be set, but cannot be read. Other location properties and methods are forbidden;
Document.href can be set, but cannot be read. Other document properties and methods are forbidden to access;
<iframe> src can be set, but cannot be read;
Javascript cross-Domain Access solution Summary