There are three ways that ajax handles cross domain in jquery

  • 2020-11-20 05:58:24
  • OfStack

Because of the JS same-origin policy, js can only access documents under the same domain name. Therefore, to achieve cross-domain, there are generally the following ways:

1. Cross-domain approach:

1. The agent

2.XHR2

XMLHTTPREQUEST Level2 (and XHR2), provided in HTML5, have implemented cross-domain access. However, ie10 or below is not supported

Just fill in the response header on the server side:


 header("Access-Control-Allow-Origin:*");
 /* The asterisk means that all fields are acceptable, */
 header("Access-Control-Allow-Methods:GET,POST");

3.jsonP

Principle:

ajax itself is not cross-domain,
Cross-domain is achieved by generating 1 script tag. Because the src attribute of the script tag has no cross-domain restrictions.

With dataType: 'jsonp' set up, the $.ajax method has nothing to do with ajax XmlHttpRequest and is replaced by the JSONP protocol. JSONP is an unofficial protocol that allows integration of Script tags on the server side back to the client for cross-domain access in the form of javascript callback.

Cross-domain writing of ajax:

(The rest of the writing method and non-cross-domain 1 sample) :

Such as


 /* The current url is localhost:3000*/
 js code 
 
 $.ajax({
 type:"get",
 url:"http://localhost:3000/showAll",/*url Write the request address of the foreign region */
 dataType:"jsonp",/* add datatype*/
 jsonpCallback:"cb",/* Set up the 1 A callback function with the same name as the function below */
 success:function(){
  . 
 }
 });

 /* On the foreign server, */
 app.js
 app.get('/showAll',students.showAll);/* This is the same as the non-cross domain notation */
 
 
 /* At the exotic server showAll The function, */

 var db = require("./database");

 exports.showAll = function(req,res){

 /** Setting the response header is allowed ajax Cross domain access **/
 res.setHeader("Access-Control-Allow-Origin","*");
 /* The asterisk indicates that all foreign requests are acceptable, */
 res.setHeader("Access-Control-Allow-Methods","GET,POST");

 var con = db.getCon();
 con.query("select * from t_students",function(error,rows){
 if(error){
 console.log(" Database error: "+error);
 }else{
 /* Notice here, what's returned is jsonP The name of the callback function + The data */
 res.send("cb("+JSON.stringify(r)+")");
 }
 });
 }

2. Solve the cross-domain approach of ajax and JQuery

JS cross-domain problem, I think many programmers in the mind that JS is not cross-domain, in fact this is a wrong point of view; There are a lot of people on the Internet looking for its solution, teach it to use IFRAME to solve a lot of articles, is it really that complicated? It's pretty simple, if you use JQUERY, 1 GETJSON method, and it's 1 line of code.

Now let's start Posting the method.


// Cross domain (across all domain names) 
$.getJSON("http://user.hnce.com.cn/getregion.aspx?id=0&jsoncallback=?",function(json){ 
// The data format of the requested remote request page is:  ?(json_data) // Such as:  //?([{"_name":" Hunan province ","_regionId":134},{"_name":" The Beijing municipal ","_regionId":143}]) alert(json[0]._name); 
}); 

$.getJSON("http://user.hnce.com.cn/getregion.aspx?id=0&jsoncallback=?",function(json){ 
// The data format of the requested remote request page is:  ?(json_data) // Such as:  //?([{"_name":" Hunan province ","_regionId":134},{"_name":" The Beijing municipal ","_regionId":143}]) alert(json[0]._name); 
}); 


Note that in ES70en. aspx, when output JSON data, 1 must use ES73en. QueryString["jsoncallback"], put the acquired content in front of the returned JSON data, assuming the actual acquired value is 42342348, then the returned value is 42342348([{"_name":" Hunan Province ","_regionId":134},{"_name":" Beijing ","_regionId":143}))

Because the principle of getJSON cross domain is to put? Randomly change 1 method name, and then return the executed, to achieve the purpose of cross-domain response.

The following is a real-world example of cross-domain execution:


<script src="http://common.cnblogs.com/script/jquery.js" type="text/javascript"></script> 
<script type="text/javascript"> 
// Cross domain (across all domain names)  
$.getJSON("http://e.hnce.com.cn/tools/ajax.aspx?jsoncallback=?", { id: 0, action: 'jobcategoryjson' }, function(json) { alert(json[0].pid); alert(json[0].items[0]._name); });  
 </script> 

<script src="http://common.cnblogs.com/script/jquery.js" type="text/javascript"></script> 
<script type="text/javascript"> 
// Cross domain (across all domain names)  
$.getJSON("http://e.hnce.com.cn/tools/ajax.aspx?jsoncallback=?", { id: 0, action: 'jobcategoryjson' }, function(json) { alert(json[0].pid); alert(json[0].items[0]._name); });  
 </script> 

jQuery Cross-domain principle:

The browser does the same origin check, which causes cross-domain problems, but there is one exception to this cross-domain check: HTML < Script > Mark; We use it a lot < Script > src property, when the script static resource is placed under a separate domain name or comes from another site it's 1 url; The result of this url response can be many things, such as JSON, where the returned Json value becomes < Script > The src attribute value of the tag. This property value change does not affect the page. By convention, the browser provides a parameter in the URL query string that is returned to the browser as a prefix to the result;

Look at the following example:


<script type="text/javascript" src="http://domain2.com/getjson?jsonp=parseResponse"> </script> 
 Response values: parseResponse({"Name": "Cheeso", "Rank": 7}) 
<script type="text/javascript" src="http://domain2.com/getjson?jsonp=parseResponse"> </script> 
 Response values: parseResponse({"Name": "Cheeso", "Rank": 7}) 

This is called JsonP; (If the link is no longer valid, click here :JSONP); JSON with padding The prefix mentioned above is "padding". So how does jQuery work?

It doesn't seem to be < Script > The appearance of the mark! ? OKay, look at the source code:

The page calls getJSON:


getJSON: function( url, data, callback ) {
 return jQuery.get(url, data, callback, "json");
 },
 

Continue to follow up


 get: function( url, data, callback, type ) {
 // shift arguments if data argument was omited
 if ( jQuery.isFunction( data ) ) {
  type = type || callback;
  callback = data;
  data = null;
 }
 
 return jQuery.ajax({
  type: "GET",
  url: url,
  data: data,
  success: callback,
  dataType: type
 });

Follow up jQuery.ajax with the code snippet of the ajax method below:


 // Build temporary JSONP function
 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
 jsonp = s.jsonpCallback || ("jsonp" + jsc++);
 
 // Replace the =? sequence both in the query string and the data
 if ( s.data ) {
 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
 }
 
 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
 
 // We need to make sure
 // that a JSONP style response is executed properly
 s.dataType = "script";
 
 // Handle JSONP-style loading
 window[ jsonp ] = window[ jsonp ] || function( tmp ) {
 data = tmp;
 success();
 complete();
 // Garbage collect
 window[ jsonp ] = undefined;
 
 try {
  delete window[ jsonp ];
 } catch(e) {}
 
 if ( head ) {
  head.removeChild( script );
 }
 };
 }
 
 if ( s.dataType === "script" && s.cache === null ) {
 s.cache = false;
 }
 
 if ( s.cache === false && type === "GET" ) {
 var ts = now();
 
 // try replacing _= if it is there
 var ret = s.url.replace(rts, "$1_=" + ts + "$2");
 
 // if nothing was replaced, add timestamp to the end
 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
 }

 // If data is available, append data to url for get requests
 if ( s.data && type === "GET" ) {
 s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
 }
 
 // Watch for a new set of requests
 if ( s.global && ! jQuery.active++ ) {
 jQuery.event.trigger( "ajaxStart" );
 }
 
 // Matches an absolute URL, and saves the domain
 var parts = rurl.exec( s.url ),
 remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
 
 // If we're requesting a remote document
 // and trying to load JSON or Script with a GET
 if ( s.dataType === "script" && type === "GET" && remote ) {
 var head = document.getElementsByTagName("head")[0] || document.documentElement;
 var script = document.createElement("script");
 script.src = s.url;
 if ( s.scriptCharset ) {
 script.charset = s.scriptCharset;
 }
 
 // Handle Script loading
 if ( !jsonp ) {
 var done = false;
 
 // Attach handlers for all browsers
 script.onload = script.onreadystatechange = function() {
  if ( !done && (!this.readyState ||
  this.readyState === "loaded" || this.readyState === "complete") ) {
  done = true;
  success();
  complete();
 
  // Handle memory leak in IE
  script.onload = script.onreadystatechange = null;
  if ( head && script.parentNode ) {
  head.removeChild( script );
  }
  }
 };
 }
 
 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
 // This arises when a base node is used (#2709 and #4378).
 head.insertBefore( script, head.firstChild );
 
 // We handle everything using the script element injection
 return undefined;
 }

Lines 1 through 10: Determines that it is an JSON call, creates a temporary JsonP method for this call, and adds a random number derived from the date value;

So let's focus on line 14, which is pretty critical, and that's what's going to determine our outcome < Script > ; Then, the Script fragment is constructed, and the section is added to Head in line 95 to achieve the result.

Not only jQuery, but many js frameworks use the same cross-domain approach, which is how getJSON works across domains.

For more exciting content, please click "ajax Cross-domain Technology Summary" for further study and research.


Related articles: