JSONP(JSON with Padding)是一個非官方的協議,它允許在伺服器端整合Script tags返回到客戶端,透過javascript callback的形式實現跨域存取(這僅僅是JSONP簡單的實作形式)。
Asynchronous JavaScript and XML (Ajax ) 是驅動新一代 Web 網站(流行術語為 Web 2.0 網站)的關鍵技術。 Ajax 允許在不干擾 Web 應用程式的顯示和行為的情況下在背景進行資料擷取。使用 XMLHttpRequest 函數取得數據,它是一種 API,允許客戶端 JavaScript 透過 HTTP 連接到遠端伺服器。 Ajax 也是許多 mashup 的驅動力,它可將來自多個地方的內容集成為單一 Web 應用程式。
不過,由於受到瀏覽器的限制,該方法不允許跨域通訊。如果嘗試從不同的網域請求數據,會出現安全性錯誤。如果能控制數 據駐留的遠端伺服器且每個要求都前往同一網域,就可以避免這些安全錯誤。但是,如果僅停留在自己的伺服器上,Web 應用程式還有什麼用處呢?如果需要從多個第三方伺服器收集資料時,又該怎麼辦?
瞭解同源策略限制
同源策略阻止從一個網域上載入的腳本取得或操作另一個網域上的文件屬性。也就是說,受到請求的 URL 的網域必須與目前 Web 頁面的網域相同。這意味著瀏覽器隔離來自不同來源的內容,以防止它們之間的操作。這個瀏覽器策略很舊,從 Netscape Navigator 2.0 版本就存在。
克服該限制的一個相對簡單的方法是讓 Web 頁面向它源自的 Web 伺服器請求數據,並且讓 Web 伺服器像代理一樣將請求轉發給真正的第三方伺服器。儘管該技術獲得了普遍使用,但它是不可伸縮的。另一種方式是使用框架要素在目前 Web 頁面中建立新區域,並且使用 GET 請求取得任何第三方資源。不過,取得資源後,框架中的內容會受到同源策略的限制。
克服該限制更理想方法是在 Web 頁面中插入動態腳本元素,該頁面來源指向其他網域中的服務 URL 並且在自身腳本中取得資料。腳本載入時它開始執行。該方法是可行的,因為同源策略不會阻止動態腳本插入,並且將腳本視為從提供 Web 頁面的網域上載入的。但如果該腳本嘗試從另一個網域載入文檔,就不會成功。幸運的是,透過添加 JavaScript Object Notation (JSON) 可以改進該技術。
1、什麼是JSONP?
要了解JSONP,不得不提一下JSON,那麼什麼是JSON ?
JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.
JSONP(JSON with Padding )是一個非官方的協議,它允許在伺服器端整合Script tags返回到客戶端,透過javascript callback的形式實現跨域存取(這僅僅是JSONP簡單的實作形式)。
2、JSONP有什麼用?
由於同源策略的限制,XmlHttpRequest只允許請求目前來源(網域名稱、協定、連接埠)的資源,為了實現跨網域請求,可以透過script標籤實作跨網域請求,然後在服務端輸出JSON資料並執行回調函數,從而解決了跨域的資料請求。
3、如何使用JSONP?
下邊這一DEMO其實是JSONP的簡單表現形式,在客戶端宣告回呼函數之後,客戶端透過script標籤向伺服器跨網域請求數據,然後服務端傳回對應的資料並動態執行回呼函數。
HTML程式碼(任一):
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <script type="text/javascript"> function jsonpCallback(result) { //alert(result); for(var i in result) { alert(i+":"+result[i]);//循环输出a:1,b:2,etc. } } var JSONP=document.createElement("script"); JSONP.type="text/javascript"; JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback"; document.getElementsByTagName("head")[0].appendChild(JSONP); </script>
或
Html程式碼
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> <script type="text/javascript"> function jsonpCallback(result) { alert(result.a); alert(result.b); alert(result.c); for(var i in result) { alert(i+":"+result[i]);//循环输出a:1,b:2,etc. } } </script> <script type="text/javascript" src="http://crossdomain.com/services.php?callback=jsonpCallback"></script>
JavaScript的鏈接,必須在function的下面。
服務端PHP程式碼 (services.php):
<?php //服务端返回JSON数据 $arr=array('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5); $result=json_encode($arr); //echo $_GET['callback'].'("Hello,World!")'; //echo $_GET['callback']."($result)"; //动态执行回调函数 $callback=$_GET['callback']; echo $callback."($result)";
如果將上述JS客戶端程式碼用jQuery的方法來實現,也非常簡單。
$.getJSON
$.ajax
$.get
客戶端JS程式碼在jQuery中的實作方式1:
##Js程式碼
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $.getJSON("http://crossdomain.com/services.php?callback=?", function(result) { for(var i in result) { alert(i+":"+result[i]);//循环输出a:1,b:2,etc. } }); </script>客戶端JS程式碼在jQuery中的實作方式2:
Js程式碼
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $.ajax({ url:"http://crossdomain.com/services.php", dataType:'jsonp', data:'', jsonp:'callback', success:function(result) { for(var i in result) { alert(i+":"+result[i]);//循环输出a:1,b:2,etc. } }, timeout:3000 }); </script>客戶端JS程式碼在jQuery中的實作方式3:
Js程式碼
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $.get('http://crossdomain.com/services.php?callback=?', {name: encodeURIComponent('tester')}, function (json) { for(var i in json) alert(i+":"+json[i]); }, 'jsonp'); </script>其中jsonCallback 是客戶端註冊的,取得跨網域伺服器上的json資料後,回呼的函數。
http://crossdomain.com/services.php?callback=jsonpCallback
這個url 是跨域伺服器取json 資料的接口,參數為回調函數的名字,返回的格式為
Js程式碼
jsonpCallback({msg:'this is json data'})
Jsonp原理:
先在客戶端註冊一個callback, 然後把callback的名字傳給伺服器。 此時,伺服器先生成 json 資料。 接著以 javascript 語法的方式,產生一個function , function 名字就是傳遞上來的參數 jsonp.最後將 json 資料直接以入參的方式,放置到 function 中,這樣就產生了一段 js 語法的文檔,傳回給客戶端。
客戶端瀏覽器,解析script標籤,並執行返回的javascript 文檔,此時數據作為參數,傳入到了客戶端預先定義好的callback 函數裡.(動態執行回調函數)
使用JSON的優點在於:
比XML輕了許多,沒有那麼多冗餘的東西。
JSON也是具有很好的可讀性的,但是通常回傳的都是壓縮過後的。不像XML這樣的瀏覽器可以直接顯示,瀏覽器對於JSON的格式化的顯示就需要藉助一些插件了。
在JavaScript中處理JSON很簡單。
其他語言例如PHP對於JSON的支援也不錯。
JSON也有一些缺點:
JSON在服務端語言的支援不像XML那麼廣泛,不過JSON.org上提供很多語言的函式庫。
如果你使用eval()來解析的話,會容易出現安全性問題。
儘管如此,JSON的優點還是很明顯的。他是Ajax資料互動的很理想的資料格式。
主要提示:
JSONP 是建構 mashup 的強大技術,但不幸的是,它並不是所有跨域通訊需求的萬靈藥。它有一些缺陷,在提交開發資源之前必須認真考慮它們。
第一,也是最重要的一點,沒有關於 JSONP 呼叫的錯誤處理。如果動態腳本插入有效,就執行呼叫;如果無效,就靜默失敗。失敗是沒有任何提示的。例如,不能從伺服器捕捉 404 錯誤,也不能取消或重新開始要求。不過,等待一段時間還沒回應的話,就不用理它了。 (未來的 jQuery 版本可能有終止 JSONP 請求的特性)。
JSONP 的另一個主要缺陷是被不信任的服務使用時會很危險。因為 JSONP 服務傳回打包在函數呼叫中的 JSON 回應,而函數呼叫是由瀏覽器執行的,這使得宿主 Web 應用程式更容易受到各類攻擊。如果打算使用 JSONP 服務,了解它能造成的威脅非常重要。
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
#以上是AJAX跨域請求之JSONP取得JSON數據的詳細內容。更多資訊請關注PHP中文網其他相關文章!