Cross-origin JavaScript

Source: Internet
Author: User
Tags file url subdomain name

This Policy imposes significant limitations on the page content that JavaScript code can access, that is, JavaScript can only access content in the same domain as the document containing it.

JavaScript, a security policy, is particularly important in Multi-iframe or Multi-Window Programming and Ajax programming. According to this policy, the JavaScript code contained in the page under baidu.com cannot access the page content under the google.com domain name; even pages of different subdomains cannot be accessed through JavaScript code. The effect 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.

However, when some in-depth front-end programming is required, cross-origin operations are inevitable. At this time, the "same-origin policy" is too harsh. This article summarizes some of the technologies required for cross-origin.

We will discuss cross-origin Technology in two cases: first, we will discuss cross-origin Technology for different subdomains, and then we will discuss cross-origin Technology for completely different domains.

(1) Cross-Domain Technology for different subdomains.

We will discuss the following two questions: the first is how to call JavaScript across different subdomains, and the second is how to submit Ajax requests to different subdomains.

First, let's solve the first problem. Assume that the example.com domain has two different subdomains: abc.example.com and def.example.com. Now suppose there is a page under def.example.com, which defines a JavaScript function:
Copy codeThe Code is as follows: function funcInDef (){
.....
}
We want to call the above function on a page under abc.example.com. Suppose that the page under abc.example.com we want to discuss is embedded in the page under def.example.com in the form of iframe, so we may try to make the following calls in iframe:

Copy codeThe Code is as follows: window. top. funcInDef ();
Well, we noticed that this call is forbidden by the "same-origin policy" mentioned above, and the JavaScript engine will directly throw an exception.
To implement the preceding call, We can modify the domain attribute of two pages. For example, we can add the following JavaScript code snippets to the top of the two pages above under abc.example.com and def.example.com:
Copy codeThe Code is as follows: document. domain = "example.com ";

In this way, the two pages are changed to the same domain, and the previous call can also be executed normally.

Note that the document of a page. the domain attribute can only be set to a higher-level domain name (except the first-level domain name), but cannot be set to a subdomain name deeper than the current domain name. For example, a page of abc.example.com can only set its domain to example.com, not sub.abc.example.com, or a top-level domain name com.

The preceding example shows that two pages are nested with iframe. When two pages are opened and opened, the principle is the same.

Next we will solve the second problem: how to submit Ajax requests to different subdomains.
Generally, we use code similar to the following to create an XMLHttpRequest object:
Copy codeThe Code is as follows: 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 above code references ActiveXObject to be compatible with the IE6 series browsers. Every time we call the newRequest function, we get a newly created Ajax object and use this Ajax object to send an HTTP request. For example, the following code sends a GET request to abc.example.com:
Copy codeThe Code is as follows:
Var request = newRequest ();
Request. open ("GET", "http://abc.example.com ");
Request. send (null );

If the above Code is included in a page under the abc.example.com domain name, the GET request can be sent successfully without any problems. However, if you want to send a request to def.example.com, a cross-origin problem occurs and the JavaScript engine throws an exception.
Add the following to the top of the page for calling Ajax in the examples file and in the abc.example.com domain:
Copy codeThe Code is as follows: document. domain = "example.com ";

To use cross-origin files, we embed a hidden iframe pointing to cross-origin files on the page that calls Ajax in the abc.example.com domain. For example:
Copy codeThe Code is as follows: <iframe name = "xd_iframe" style = "display: none" src = "http://def.example.com/crossdomain.html">
</Iframe>

NewRequest function in response:
Copy codeThe Code is as follows: var request = window. frames ["xd_iframe"]. newRequest ();
In this way, the request object can be sent to the http://def.example.com HTTP request.

(2) Cross-Domain Technology with different domains.

If the top-level domain names are not the same, for example, example1.com and example2.com want to communicate with each other through JavaScript on the frontend, the technology required is more complex.

Before explaining the Cross-Domain Technology for different domains, we should first make it clear that the technology to be discussed below also applies to the previous cross-different subdomains, because cross-domain is only a special case of Cross-Domain issues. Of course, the use of appropriate technologies under appropriate circumstances can ensure better efficiency and higher stability.

In short, cross-origin technology can be classified into the following categories based on different cross-origin needs:
1. JSONP cross-origin GET request
2. implement cross-origin through iframe
3. flash cross-origin HTTP Request
4. window. postMessage
The following describes various technologies in detail.
1. JSONP.
The method used to create a <script> node on the page to submit HTTP requests to different domains is called JSONP. This technology can solve the problem of cross-origin Ajax request submission. The working principle of JSONP is described as follows:
Assume that:
Copy codeThe Code is as follows: var eleScript = document. createElement ("script ");
EleScript. type = "text/javascript ";
EleScript. src = "http://example2.com/getinfo.php ";
Document. getElementsByTagName ("HEAD") [0]. appendChild (eleScript );

When a GET request is sent from.

JSONP has the following advantages: it is not subject to same-origin policy restrictions as Ajax requests implemented by XMLHttpRequest objects; it has better compatibility and can be run in older browsers, XMLHttpRequest or ActiveX is not required. After the request is completed, you can call callback to return the result.

The disadvantage of JSONP is that it only supports GET requests but not POST and other types of HTTP requests. It only supports cross-origin HTTP requests, it cannot solve the problem of how to call JavaScript between two pages in different domains.

2. Use iframe to implement cross-origin.

The iframe cross-origin method is more powerful than JSONP. It can be used not only to complete HTTP requests across domains, but also to implement JavaScript calls at the front-end cross-origin. Therefore, iframe is usually used to solve cross-domain problems across different domains.

Similar to the JSONP technique, when creating a <script> node to submit a GET request to different domains, we can also. However, the result returned by the request cannot be called back to the callbackresponse in the http://example1.com/index.php page, because it is affected by the same source policy.

To solve this problem, we need to place a cross-domain file under example1.com, for example, the path is http://example1.com/crossdomain.html.

When the request returns a result at http://example2.com/getinfo.php, there are two choices on the response page.
The first choice is that it can perform a 302 jump in iframe to jump to the Cross-Domain file seek? Result = <URL-Encoding-Content>.

Another choice is that it can embed an iframe in the returned page to point to a cross-origin file, and also fix the returned result after URL encoding as a parameter after the cross-origin File URL.

The cross-origin file contains a piece of JavaScript code. The function of this Code is to extract the result parameters from the URL. After some processing, call a pre-defined callbackresponse on the original http://example1.com/index.php page to deliver the result to this handler. The http://example1.com/index.php page and the Cross-Domain file are in the same domain. You can use this region. The iframe of the Cross-origin file and the original region.

Based on the previous descriptions, with cross-origin files, we can implement JavaScript calls between different domains using iframe. This call process can be completely unrelated to HTTP requests. For example, some sites can dynamically adjust the height of the third-party iframe embedded in the page, in fact, this is done by detecting the height change of your page in the third-party iframe, and then notifying the parent window of this change through function calls in the Cross-origin mode.

Since iframe can be used to implement cross-origin JavaScript calls, it is not difficult to submit POST requests and other types of HTTP requests across domains. For example, we can call the JavaScript code of the target domain across domains to submit Ajax requests (GET/POST/etc.) In the target domain, and then pass the returned results to the original domain across domains.

Using iframe for cross-origin, the advantage is that it is powerful and supports a variety of browsers to accomplish almost any cross-origin tasks. The disadvantage is that the implementation is complicated and many browser compatibility problems need to be handled, in addition, the transmitted data should not be too large. If it is too large, it may exceed the browser's limit on the URL length. We should consider performing segment transmission on the data.

3. Use flash to implement cross-origin HTTP requests

It is said that the popularity of flash in browsers is as high as 90% or more.

Flash code and JavaScript code can call each other, and the "Security Sandbox" mechanism of flash is different from that of JavaScript. Therefore, we can use flash to submit HTTP requests across domains (such as GET and POST are supported ).
For example, we use a browser to access ingress.

Whether the request is successfully sent depends on whether a crossdomain. xml file is placed in the root path of example3.com and how the crossdomain. xml file is configured. Flash's "security sandbox" ensures that only when the example3.com server is indeed placed under the root path. the request is successful only when the xml file is configured to allow the request to accept flash requests from example2.com. The following is an example of crossdomain. xml file content:

Copy codeThe Code is as follows:
<? Xml version = "1.0"?>
<Cross-domain-policy>
<Allow-access-from domain = "example2.com"/>
</Cross-domain-policy>

4. window. postMessage
Window. postMessage is a new feature supported by html5. Due to the rapid development of Internet technology, the demand for cross-origin communication for browsers is getting stronger and stronger, and the HTML standard has finally taken cross-origin communication into consideration. Currently, HTML5 is only a draft.
Window. postMessage is a secure method for implementing direct cross-origin communication. Currently, not all browsers support this function. Only Firefox 3, Safari 4, and IE8 support this function.

The calling method for sending messages to other windows is as follows:
Copy codeThe Code is as follows: otherWindow. postMessage (message, targetOrigin );
In the receiving window, you need to set an event processing function to receive and send messages:
Copy codeThe Code is as follows: window. addEventListener ("message", receiveMessage, false );
Function receiveMessage (event ){
If (event. origin! = "Http://example.org: 8080") return;
}
A message contains three attributes: data, origin (containing the real information of the domain where the sending window is located), and source (representing the handle of the sending window ).

Security considerations: to use window. postMessage, you must use the origin and source attributes of the message to verify the sender's identity. Otherwise, an XSS vulnerability may occur.

Window. postMessage is equally powerful in terms of functions and cross-domain functions implemented by iframe. It is easy to use and more efficient, but its disadvantage is that it still needs to be improved in browser compatibility.

In the original article, the vulnerability that can be assigned to an Object or Function by using the Opener of IE in IE6 and IE7 provides a supplementary postMessage solution:
Home page:

Copy codeThe Code is as follows:
<! 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 in other domains:

Copy codeThe Code is as follows:
<! 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>

Note: The postMessage method is being supported by various new browsers at an unexpected speed and should be taken into consideration.

Related Article

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.