In-depth analysis of Javascript cross-origin issues, in-depth analysis of javascript

Source: Internet
Author: User

In-depth analysis of Javascript cross-origin issues, in-depth analysis of javascript

What is cross-origin?

Assume that the js of the slave (non-same-source) server modifies the content of the website.
Reference a table to check the cross-cause conditions:

But sometimes we do need to do this, so what methods do we have?

1. JsonP

Jsonp cannot be mentioned before cross-origin is mentioned. Jsonp is short for JavacScript Object Notation with Padding. It can be understood as json data filled with content.
Because the preceding statements declare callback and call data. js of the external domain B .com, and data. js calls:
Callback ({msg: "tqtan "});
In this way, when the js that calls the reference external domain, it will call the local callback () for data transmission.
The above is just a simple cross-origin. Let's look at the real use of jQuery.

Ajax in jQuery can pull data from external domains in two ways:

1. $. getJSON ()

This method is simple and crude, and requests the external domain Json.

Copy codeThe Code is as follows:
$. GetJSON ("http:// B .com/dataServlet? Callback =? ", Function (data ){
Console. log (data. msg );
});

Assume that the above request accesses the servlet page under B .com and the passed parameter is callback = ?, JQuery will automatically generate a string to fill the placeholder ?, For example, callback = jQuery17207481773362960666_1332575486681. This declares the unique identifier with the server. The server only needs to return the json format data with this callback value. For example:

Copy codeThe Code is as follows:
// DataServlet. java
String callback = req. getParameter ("callback ");
PrintWriter out = resp. getWriter ();
Out. print (callback + "('msg ', 'tqtan ')");

In this way, data from non-same-source servers can be obtained successfully.

2. $. ajax ()

The implementation principle is the same as above, but more links can be customized.

$.ajax({url:'http://b.com/dataServlet?words=hi',dataType:'jsonp',jsonp : 'jsoncallback',jsoncallback : 'tqtan',success:function(data){console.log(data.msg);},error: function (e) {console.log(e);}});

You can customize the callback name. Here it is changed to 'tqtan ', and the value of words = hi can be passed here.
Note that the JsonP format can only be used to request the server in GET format.

2. document. domain

This method is only applicable to cross-domains with the same primary domain and different subdomains.
That is, the cross-domain problem between get.a.com and data.com. The solution is simple:
If.

// Get.html var iframe = document. creatElement ("iframe"); iframe. src = "http://data.a.com/data.html"; iframe. style. display = "none"; document. body. appendChild (iframe); document. domain = 'a. com '; iframe. onload = function () {var otherDocument = iframe. contentDocument | iframe.content20.doc ument; // otherDocument is the document of another page // do whatever you want ..}; // data.html document. domain = 'a. com ';

3. url hash

You can also implement cross-origin through url hash. Hash is the content after url #, such as http://targetkiller.net/index.html#data. here, data=hash. How can we use this to implement cross-origin?

Or that example, Example. In addition, data.html responds to the obtained hash, and also creates an iframe. src points to a.com/proxy.html and redirects the corresponding data to hash1. Then, a.com/proxy.htmlonly modifies the hashvalue of get.htmlin the same a.comparent domain. Finally, how can we get data? Only when you write a timer setInterval in get.html, You can periodically listen for new hash information.

Here, you may feel confused. There are several problems:

1.proxy.html?
Response.
A.com/get.html

Var iframe = document. createElement ('iframe'); iframe. src = 'HTTP: // a.com/get.html?data'=iframe.style.display = 'none'; document. body. appendChild (iframe); // periodically checks the hash update function getHash () {var data = location. hash? Location. hash. substring (1): ''; console. log (data) ;}var hashInt = setInterval (function () {getHash ()}, 1000); a.com/proxy.htmlparent.location.hash = self. location. hash. substring (1); B .com/data.html//simulate a simple processing operation if (location. hash) {var data = location. hash; dosomething (data);} function dosomething (data) {console. log ("from a.com:" + data); var msg = "hello I am B .com"; var iframe = document. createElement ('iframe'); iframe. src = "http://a.com/proxy.html#" + msg; iframe. style. display = 'none'; document. body. appendChild (iframe );}

4. window. name

This method is clever. It refers to the explanation of the circle center. The name value still exists after loading on different pages (or even different domain names) and supports a very long name value (2 MB ).
The specific example is still the above, and a proxy page is also required.
Bytes. In the same time, set window. name = data in data.html; assign a value to window. name. After the onload event, immediately jump the iframe to the local a.com/proxy.html. In this case, too many namespaces are shared to find an iframe in srcfor proxy.html, and the next step is to obtain values from the same source.
A.com/get.html

Var state = 0, iframe = document. createElement ('iframe'), iframe. src = 'HTTP: // B .com/data.html "; iframe. style. display = 'none'; loadfn = function () {if (state = 1) {var data = iframe. contentWindow. name; console. log (data);} else if (state = 0) {state = 1; // jump to proxy.html iframe. contentWindow. location = "http://a.com/proxy.html" ;}}; if (iframe. attachEvent) {iframe. attachEvent ('onload', loadfn);} else {iframe. onload = loadfn;} document. body. appendChild (iframe); a.com/proxy.html// proxy.html must be used to delete the iframeof get.html and avoid security issues. write (''); iframe. contentWindow. close (); document. body. removeChild (iframe); B .com/data.htmlvar data = "hello, tqtan"; window. name = data;

5. postMessage ()

The new postMessage () method of html5 elegantly solves cross-domain issues and is easy to understand.
The sender calls the postMessage () content and the receiver listens to the onmessage content.
Assume that the sender is a.com/send.htmland the receiver is B .com/receive.html.
A.com/send.html

Var iframe = document. createElement ("iframe"); iframe. src = "http:// B .com/receive.html"; document. body. appendChild (iframe); iframe. contentWindow. postMessage ("hello", "http:// B .com"); B .com/receive.html?addeventlistener ('message', function (event) {// determine the message source address if (event. origin = 'HTTP: // a.com ') {console. log (event. data); console. log (event. source); // The window value of the sending source }}, false );

6. CORS (background implementation)

The above five points are cross-origin implemented by the front-end, but background participation makes cross-origin easier to solve, that is, CORS.
CORS is short for Cross-Origin Resource Sharing, that is, Cross-Origin Resource Sharing. How awesome is it? Previously, JsonP can only get requests, but CORS can accept all types of http requests. However, CORS is only supported by modern browsers.
How to use it? You only need to send common ajax requests to the front end. Check the support of CORS. Referenced by Jiang Yujie.

Function createCORSRequest (method, url) {var xhr = new XMLHttpRequest (); if ("withCredentials" in xhr) {// CORS is supported at this time. // check whether the XMLHttpRequest object has the "withCredentials" attribute. // "withCredentials" only exists in the XMLHTTPRequest2 object xhr. open (method, url, true);} else if (typeof! = "Undefined") {// otherwise, check whether XDomainRequest is supported. IE8 and IE9 support it. // XDomainRequest is only available in IE, is the method in which IE is used to support CORS requests xhr = new XDomainRequest (); xhr. open (method, url);} else {// otherwise, the browser does not support CORSxhr = null;} return xhr;} var xhr = createCORSRequest ('get', url ); if (! Xhr) {throw new Error ('cors not ororted ');}

At the same time, the server only needs to set the Access-Control-Allow-Origin header.

In java, you only need to set

Copy codeThe Code is as follows:
Response. setHeader ("Access-Control-Allow-Origin ","*");

For security, you can also change * to a specific domain name, such as a.com.

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.