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