1. 程式人生 > 程式設計 >jQuery中getJSON跨域原理的深入講解

jQuery中getJSON跨域原理的深入講解

前幾天我在開發一個工具的時候,其中有個功能就是獲取本頁面的短網址。

這個想法是好的,可是在我付諸於行動的時候,發現這個需要跨域。

起初我的想法就是,跨域的最簡單的方法就是增加一個script標籤,因為script標籤是允許跨域的。

但是問題又來了,對方的API返回的是個json物件,用script標籤只能執行,卻不能獲取到裡面的東西,也就是說返回的東西是不可控的。

隨後我就想到了jQuery中的getJSON的方法,學習了一下,沒想到裡面的文章這麼大。

jQuery非常聰明,他也意識到只靠script請求是無法接受到返回的東西的,所以他就設計了一個全域性的callback函式,傳送請求的時候把這個callback函式也傳進去。

伺服器判斷是否有這個callback函式,如果沒有就返回一個物件,如果有就返回一個函式名(物件)。

我們可以通過下面這個地址來看一下

http://to.ly/api.php?json=1&longurl=http%3A%2F%2Fwww.skiyo.cn

大家可以開啟一下,結果返回的是一個json物件。

如果我加上callback引數

http://to.ly/api.php?json=1&longurl=http%3A%2F%2Fwww.skiyo.cn&callback=somefunc

大家可以看到返回的是

somefunc({“shorturl”: “http:\/\/to.ly\/3XHP”,“ok”: true})

傳入的也正好是函式名。

這個想法很不錯,缺點就是對方伺服器必須是可控的。

大方向是這個的,但是還有一些細節的小技巧,比如說如何在匿名函式中設定一個全域性函式,如何將這個全域性函式變為匿名函式!

本來想直接把jQuery中的getJSON拿來直接用的,可是看了才知道,jQuery的ajax方法都混合到一起了,想剝落下來也不是一件容易的事。

慶幸的是我還懂一點JavaScript,經過我的加工與修改,下面的例子已經可以正常使用。詳細的可以檢視註釋。

以下是程式碼片段:

(function() {
 var cross = {
 //設定一個隨機的callback函式..防止跟其他的全域性函式重名
 callback : 'cross' + parseInt(Math.random()*1000),init : function() {
 this.getJSON('http://to.ly/api.php?json=1&longurl='+encodeURIComponent('http://www.skiyo.cn/'),function(data){
 alert(data.shorturl);
 });
 },getJSON : function(url,callback) {
 var c = this.callback;
 url = url + "&callback=" + c;
 // Handle JSONP-style loading
 //將函式名設定為window的一個方法,這樣此方法就是全域性的了.
 window[ c ] = window[ c ] || function( data ) {
 //呼叫匿名函式
 callback(data);
 // Garbage collect
 window[ c ] = undefined;
 try {
  delete window[ c ];
 } catch(e) {}
 if ( head ) {
  head.removeChild( script );
 }
 };
 var head = document.getElementsByTagName("head")[0] || document.documentElement;
 var script = document.createElement("script");
 script.src = url;
 // Handle Script loading
 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;
  // Handle memory leak in IE
  script.onload = script.onreadystatechange = null;
  if ( head && script.parentNode ) {
  head.removeChild( script );
  }
 }
 };
 head.insertBefore( script,head.firstChild );
 },};
 //go
 cross.init();
})();

總結

到此這篇關於jQuery中getJSON跨域原理的文章就介紹到這了,更多相關jQuery getJSON跨域原理內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!