In-depth understanding of front-end cross-domain methods and principles

Source: Internet
Author: User

Objective

Subject to browser-origin policy, JS in this domain cannot manipulate page objects (such as the DOM) of other domains. But the security restrictions also bring a lot of trouble to inject IFRAME or AJAX applications. So we have to use some methods to make this domain JS able to manipulate other domain page objects or make other domain JS can manipulate the domain's page objects (IFRAME).

Here need to be clear: the so-called domain is not related to JS storage server, such as Baidu.com page loaded google.com js, then this JS domain is baidu.com instead of google.com. In other words, this JS can manipulate the Baidu.com Page object, and cannot manipulate the Google.com Page object.

Summary of cross-domain methods

One-way cross-domain (typically used to get data)

One, using Jsonp cross-domain

Principle: Because JS introduced through the script tag is not limited by the same-origin policy (as mentioned in the previous article baidu.com page loaded google.com js). So we can use the script tag to introduce a JS or a other suffix form (such as php,jsp, etc.) of the file, this file returns a JS function call, such as return Jsonp_getusers (["Paco", "John", "Lili"]), That is, the results returned by this file call the Jsonp_getusers function, and the ["Paco", "John", "Lili"] are passed in, this ["Paco", "John", "Lili") is a user list. So if there is a jsonp_getusers function in our page at this point, then Jsonp_getusers is called and the user list is passed in. This enables the ability to get additional domain data in the domain, that is, cross-domain.

The implementation examples are as follows:

The front-end introduces remote JS and defines a good jsonp_getusers function, note that you need to define the Jsonp_getusers function first, to avoid the remote JS loading completed and call Jsonp_getusers, this function does not exist:

[HTML]View PlainCopyprint?
    1. This domain is baidu.com
    2. <script>
    3. function Jsonp_getusers (users) {
    4. Console.dir (users);
    5. }
    6. </Script>
    7. Load the google.com getusers.php
    8. <script src="http://www.google.com/getUsers.php"></script>

Google.com is required to provide support, getusers.php code is as follows:

[HTML]View PlainCopyprint?
    1. <? php>
    2. Echo ' Jsonp_getusers (["Paco", "John", "Lili"]) ';//returns the invocation of a JS function
    3. ?>

Why is the file introduced by the script tag not limited by the same-origin policy? Because the file content introduced by the script tag cannot be obtained by the client's JS, it does not affect the security of the referenced file, so it is not necessary to make the file introduced by the script tag conform to the browser's homologous policy. And the content of the file loaded by Ajax can be obtained by the client JS, so Ajax must follow the same-origin policy, otherwise the contents of the introduced file will be leaked or there are other risks.

The disadvantage of JSONP is that it only supports get requests and does not support other types of HTTP requests such as post (although using post+ to dynamically generate an IFRAME can achieve the purpose of post cross-domain, this is a more extreme way, not recommended). A general GET request can perform all functions. For example, if you need to transfer parameters to other domain servers, you can hang parameters after the request (be careful not to hang private data), that is

[HTML]View PlainCopyprint?
    1. <script src="http://www.google.com/getUsers.php?flag=do&time=1"></Script  >.

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. You can see that the JSONP cross-domain is typically used to get data from other domains.

It is generally possible to implement cross-domain Jsonp with JSONP, which is also the most cross-domain method used in front end.

Ii. dynamic creation of script tags

This method is actually a simplified version of the Jsonp cross-domain, and JSONP only adds a callback function on this basis.

For example, the getusers.php returned in the previous example is not a JS function call, but a JS variable, such as:

[HTML]View PlainCopyprint?
    1. <? php>
    2. Echo ' var users=["Paco", "John", "Lili"] ';//returns a JS variable for users
    3. ?>

Then in this domain can be taken to the data variable, here should be careful to determine whether the script node is loaded, such as:

[HTML]View PlainCopy  print?
    1. js.onload = js.onreadystatechange =  function ()  {  
    2.     if  (! this.readystate | |  this.readystate ===  ' Loaded '  | |  this.readystate ===  ' complete ')  {  
    3. Li class= the "alt" >        console.log (users);//This removes data    from other domains;
    4.         js.onload = js.onreadystatechange = null;   
    5. &NBSP;&NBSP;&NBSP;&NBSP;}&NBSP;&NBSP;
    6. };   

Third, 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 baidu.com request domain google.com, we can use Flash to send HTTP requests. First, modify the crossdomain.xml on the domain google.com (typically stored in the root directory, if you do not need to create it manually), and add baidu.com to 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 support for iOS, this is not a good solution.

Iv. Access Control

This cross-domain approach is currently supported in only a few browsers, which can send a cross-domain HTTP request (Firefox, Google chrome, etc. via XMLHttpRequest, implemented through Xdomainrequest IE8), The requested response must contain a Access-control-allow-origin HTTP response header that declares the accessible permission for the requesting domain. For example, Baidu.com sends a cross-domain HTTP request (via Ajax) to the getusers.php under Google.com, then getusers.php must include the following response header:

[HTML]View PlainCopyprint?
    1. Header ("access-control-allow-origin:http://www.baidu.com"),//means allow baidu.com to request this file across domains

Wu, 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 (iframe.onload), 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 of the IFRAME. (Because the window.name in a and the window.name in the IFrame are independent of each other, it is not possible to get window.name directly in a, but to get its window.name through an iframe). This approach is ideal for one-way data requests, and the protocol is simple and secure. External scripts are not executed as JSONP.

Six, Server Agent

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 the baidu.com domain needs to request a resource file getusers.php under Google.com, sending a direct AJAX request to google.com/getusers.php is definitely blocked by the browser. At this point, we have an agent under Baidu.com, and then bind the AJAX request to this proxy path, such as baidu.com/proxy/, The proxy then sends an HTTP request to access the getusers.php under Google.com, and the cross-domain HTTP request is made on the server side (the server side has no same-origin policy restrictions), and the client does not produce a cross-domain Ajax request. This cross-domain approach does not require an agreement with the target resource and is aggressive.

Bidirectional cross-domain (between two iframe or two pages, generally used to get the data of the other side, Document.domain way can also directly manipulate the other side DOM)

Vii. Document.domain (between two iframe)

By modifying the domain property of document, we can communicate between domains and subdomains or different subdomains. The same domain policy considers that domains and subdomains belong to different domains, such as baidu.com and youxi.baidu.com, where we cannot invoke the JavaScript methods defined in youxi.baidu.com in the page under Baidu.com. But when we change the domain property of their document to Baidu.com, the browser will think that they are in the same domain, then we can get each other's data or manipulate the DOM.

Problem:

1, security, when one site is attacked, another site 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.

Eight, Location.hash (between two IFrame), also known as fim,fragment identitier messaging shorthand

Because the parent window can read and write URLs to the IFRAME, the IFRAME can read and write to the parent window's Url,url part is called the hash, is the # number and its subsequent characters, it is generally used for browser anchor location, the server side does not care about this part, It should be said that the HTTP request does not carry a hash, so this part of the modification will not produce an HTTP request, but will produce a browser history. The principle of this method is to change the hash portion of the URL for two-way communication. Each window sends a message by changing the location of another window (because two pages are not in the same domain ie, Chrome does not allow you to modify the value of Parent.location.hash, so use a proxy iframe under the domain name of the parent window, and receive messages by listening for changes in their URLs. This way of communication will cause some unnecessary browser history, and some browsers do not support Onhashchange events, need polling to know the URL changes, and finally, there are drawbacks, such as the data directly exposed to the URL, data capacity and type are limited and so on. The following examples illustrate:

If the parent page is a baidu.com/a.html,iframe embedded page for google.com/b.html (the URL attributes such as domain names are omitted here), the communication between the two pages can be accomplished by the following methods.

1, a.html transfer data to b.html

(1) a.html modified iframe src is Google.com/b.html#paco

(2) b.html hear the URL changes, triggering the corresponding action

2, b.html transfer data to a.html, because two pages are not in the same domain IE, chrome is not allowed to modify the value of Parent.location.hash, so to rely on a proxy iframe under the domain name of the parent window

(1) Create a hidden iframe under b.html, the src of this iframe is under the baidu.com domain, and hang the hash data to be transferred, such as src= "Http://www.baidu.com/proxy.html#data"

(2) proxy.html hear the URL changes, modify the a.html URL (because a.html and proxy.html the same domain, so proxy.html can modify a.html URL hash)

(3) a.html hear the URL changes, triggering the corresponding action

The key code for the B.html page is as follows

[HTML]View PlainCopy print?
  1. try {
  2. Parent.location.hash = ' data ';
  3. } catch (e) {
  4. IE, chrome security mechanism can not modify the Parent.location.hash,
  5. var ifrproxy = document.createelement (' iframe ');
  6. Ifrproxy.style.display = ' None ';
  7. ifrproxy.src = "Http://www.baidu.com/proxy.html#data";
  8. Document.body.appendChild (Ifrproxy);
  9. }

The key code for the Proxy.html page is as follows

[HTML]View PlainCopyprint?
    1. Because Parent.parent (that is, baidu.com/a.html) and baidu.com/proxy.html belong to the same domain, they can change the value of their location.hash
    2. Parent.parent.location.hash = self.location.hash.substring (1);

Ix. PostMessage method using HTML5 (between two iframe or two pages)

Advanced Browser Internet Explorer 8+, Chrome,firefox, Opera and Safari will support this feature. This feature mainly includes the "message" event that accepts the message and the "PostMessage" method that sends the message. For example, the a page of the baidu.com domain is embedded in a google.com Domain B page through an IFRAME, and the communication between A and B can be achieved by the following methods

A page sends a message via the PostMessage method:

[HTML]View PlainCopy print?
    1. Window.onload = function () {
    2. var IFR = document.getElementById (' IFR ');
    3. var targetorigin = "http://www.google.com";
    4. Ifr.contentWindow.postMessage (' Hello world! ', targetorigin);
    5. };

How to use PostMessage:

Otherwindow.postmessage (message, targetorigin);

Otherwindow: Refers to the target window, that is, to which window to send messages, is a member of the Window.frames property or window created by the Window.Open method

Msg: is the message to be sent, type String, Object (IE8, 9 not supported)

Targetorigin: is limited to the message receiving range, do not limit the use of ' * '

The B page listens and accepts messages through the message event:

[HTML]View PlainCopyprint?
  1. var onmessage = Function (event) {
  2. var data = event.data;//message
  3. var origin = event.origin;//message Source address
  4. var source = event.source;//Window object
  5. if (origin== "http://www.baidu.com") {
  6. Console.log (data);//hello world!
  7. }
  8. };
  9. if (typeof window.addeventlistener! = ' undefined ') {
  10. Window.addeventlistener (' message ', OnMessage, false);
  11. } else if (typeof window.attachevent! = ' undefined ') {
  12. For IE
  13. Window.attachevent (' OnMessage ', onmessage);
  14. }

Similarly, you can send a message on page B, and then the a page listens and accepts the message.

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 priority to take Location.hash, we can also use the server proxy to crawl the data without a communication agreement with the data provider.

In-depth understanding of front-end cross-domain methods and principles

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.