JQuery 的跨域方法这篇文章作者给出了使用jQuery中的getJSON方法实现跨域的方法;示例代码没有问题,但是作者把getJSON跨域的原理解释成:
“因为getJSON跨域的原理是把? 随机变一个方法名,然后返回执行的,实现跨域响应的目的。”
这个未免草率了一些,是这么回事 ?Firebug里面监控的结果貌似也是这意思,本文试图探究jQuery getJson跨域的原理;
盐从哪儿咸:为什么有跨域的问题
跨域问题存在实际上源于浏览器的同源策略(same origin policy),简单讲,同源就是要求域名,协议,端口三者都一致;而同源策略就是指页面上的脚本不能访问非同源的资源(包括HTTP响应和Cookie);上面给出了维基百科的地址,如果无法正常访问请移步这里:same origin policy
很多人会想到一个很熟悉的东西:document.domain
同源策略有点放松的就是:b.a.com上的页面无法通过a.com的同源验证,但是设置b.a.com页面的document.domain属性为a.com,就可以通过浏览器对a.com的同源检测;但是,document.domain只允许设置成更上级的域名,而不是其它域名,例如c.com就不行; 提到这里很多人都会想到多级域名下共享Cookie的路子就是把Cooki设置成上级域名;在Web2.0的时代,这种本质上同域跨级解决方案远远不能满足我们跨域的需求;
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})
这种方式被称作JsonP;(如果链接已经失效请点击这里:JSONP);即:JSON with padding 上面提到的前缀就是所谓的“padding”。那么jQuery里面是怎么实现的呢?
貌似并没有<Script>标记的出现。?OKay,翻看源码来看:
以下为引用的内容:
1 页面调用的是getJSON:
2
3 getJSON: function( url, data, callback ) {
4 return jQuery.get(url, data, callback, "json");
5 },
6
7
8 继续跟进
9
10 get: function( url, data, callback, type ) {
11 // shift arguments if data argument was omited
12 if ( jQuery.isFunction( data ) ) {
13 type = type || callback;
14 callback = data;
1
5 data = null;
16 }
17
18 return jQuery.ajax({
19 type: "GET",
20 url: url,
21 data: data,
22 success: callback,
23 dataType: type
24 });
25
26
跟进jQuery.ajax,下面是ajax方法的代码片段:
以下为引用的内容:
1 // Build temporary JSONP function
2 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
3 jsonp = s.jsonpCallback || ("jsonp" + jsc++);
4
5 // Replace the =? sequence both in the query string and the data
6 if ( s.data ) {
7 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
8 }
9
10 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
11
12 // We need to make sure
13 // that a J