一涉及到跨域的问题,相信很多人都提起精神了,因为作为开发人员时刻都想跨域,这样我们就可以获取一些数据了,那jquery作为一个 JavaScript 库怎么解决跨域问题呢?下面来我们就来给大家讲解一下。
在jQuery中的解决跨域的方法有两种getJSON和ajax
方法一:
var _url = 'http://www.a.cnblogs.com'; $.getJSON(_url, function (data) { console.log(data); })
方法二:
var _url = 'http://www.a.cnblogs.com'; $.ajax( { url: _url , data: { a: '123' , b: 'abc' } , type: 'POST' , async: false , success: function (data) { console.log(data.info); } })
jquery跨域原理是什么?
浏览器会进行同源检查,这导致了跨域问题,然而这个跨域检查还有一个例外那就是HTML的<Script>标记;我们经常使用<Script>的src属性,脚本静态资源放在独立域名下或者来自其它站点的时候这里是一个url;这个url响应的结果可以有很多种,比如JSON,返回的Json值成为<Script>标签的src属性值.这种属性值变化并不会引起页面的影响.按照惯例,浏览器在URL的查询字符串中提供一个参数,这个参数将作为结果的前缀一起返回到浏览器;
看下面的例子:
<script type="text/javascript" src="http://domain2.com/getjson?jsonp=parseResponse"> </script> 响应值: parseResponse( { "Name": "Cheeso" , "Rank": 7 }) < script type = "text/javascript" src = "http://domain2.com/getjson?jsonp=parseResponse" > </script> 响应值: parseResponse( { "Name": "Cheeso" , "Rank": 7 })
这种方式被称作JsonP;(如果链接已经失效请点击这里:JSONP);即:JSON with padding
上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢?
貌似并没有<Script> 标记的出现!?OKay,翻看源码来看:
页面调用的是getJSON:
getJSON: function (url, data, callback) { return jQuery.get(url, data, callback, "json"); },
继续跟进
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 });
跟进jQuery.ajax,下面是ajax方法的代码片段:
// 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; }
上面的代码第1行到第10行:判断是JSON类型调用,为本次调用创建临时的JsonP方法,并且添加了一个随机数字,这个数字源于用日期值;关注第14行,这一行相当关键,注定了我们的结果最终是<Script>,然后是构造Script片段,第95行在Head中添加该片段,修成正果;
其实我们了解jQuery跨域的原理就能知道解决跨域的问题了,因此我们可以自己尝试着去解决一下,提高自己的成就感哦!最后大家如果想要了解更多其他工具教程知识,敬请关注奇Q工具网。
推荐阅读:
struts的配置文件是什么?如何配置struts自动提示功能?