ajax的json和jsop的區別,解決json報錯問題

注:本文歡迎轉載,以下爲本人親測,轉載請註明:http://blog.csdn.net/wqmain/article/details/8905287


插件介紹:衆所周知,使用ajax直接發起請求存在跨域無權限訪問的問題,這時候,需要使用jsonp協議(非官方的協議)處理,jQuery中的$.ajax方法也直接支持使用該協議進行跨域訪問。下面首先介紹使用jQuery的$.ajax方法進行跨域訪問,然後再介紹使用其它jQuery插件(jQuery-JSONP)實現樣的功能。


1、新建一個jsp頁面,加入一段js代碼內容如下:

[javascript] view plain copy
  1. <script type="text/javascript">    
  2. function ajaxtest() {    
  3. $.ajax({    
  4.    url:'http://192.168.10.111/demo/testjson',    
  5.    data:{rel:13},    
  6.    dataType:"jsonp",    
  7.    jsonp:"callback",    
  8.    jsonpCallback:"success_jsonp",    
  9.    timeout:3000,    
  10.    dataFilter:function(json){    
  11.        console.log("jsonp.filter:"+json);    
  12.        return json;    
  13.    },    
  14.    success:function(json,textStatus){    
  15.        console.log("jsonp.success:"+json.name);    
  16.    },    
  17.    error:function(XMLHttpRequest,textStatus,errorThrown){    
  18.        console.log("jsonp.error:"+textStatus);    
  19.    }    
  20. });    
  21. }    
  22. </script>   

再添加一個按鈕用來測試該js方法,如下:

[html] view plain copy
  1. <input type="button" value="ajaxtest" onclick="ajaxtest()"/>  
說明:當點擊 ajaxtest 按鈕時,就會發起一個請求,由url、dataType、jsonp等參數可知,ajax使用jsonp協議向 http://192.168.10.111/demo/testjson 這個地址發起請求,並自動在url後追加callback參數,實際請求的url地址應爲:http://192.168.10.111/demo/testjson?rel=13&callback=success_jsonp,請求超時時間爲3秒,接收的數據爲json格式字符串。如果成功接收到遠程方法返回的json數據並且格式正確的話,首先會進入dataFilter方法(你可以在這個方法內對返回的json數據進行預處理,比如過濾、更改json數據等),然後進入success方法;如果請求失敗或者返回的json數據格式不正確的話會直接進入error方法。

那麼服務端的testjson方法應該返回什麼樣的數據呢?直接返回json對象或json字符串是不對的!還需要在之前加上請求時傳過來的callback的參數值,後臺(以servlet爲例)應類似如下處理:

[java] view plain copy
  1. public void testjson(HttpServletRequest request, HttpServletResponse response) {  
  2.     String callback = (String)request.getParameter("callback");  
  3.     String jsonData = "{\"id\":\"3\", \"name\":"zhangsan", \"telephone\":"13612345678"}";//爲了演示效果,json數據是寫死的  
  4.     String retStr = callback + "(" + jsonData + ")";  
  5.     response.getWriter().print(retStr);  
  6. }  

這樣後臺響應的的數據實際爲:success_jsonp({"id":"3", "name":"zhangsan", "telephone":"13612345678"})    其中success_jsonp取決於ajax參數值的設定,如果未設定,jQuery將會自動生成一個名字作爲callback的參數值。總之,後臺只需request接收parameter後,動態拼接callback變量的值就可以了。

如果返回的數據格式不按上述講的這樣,請求就會失敗並直接進入ajax的error方法。像 Uncaught SyntaxError: Unexpected token :類似這種錯誤就是返回的json數據沒用“(”和“)”小括號包起來或者前面沒加callback值而引起的


跨域調用功能除了用Query的$.ajax方法可以實現外,網絡上還有其它衆多的jQuery插件可以完成,下面就來看一下使用jQuery的jsonp插件來進行跨域調用:

首先在之前創建的jsp頁面中引入jQuery-JSONP插件並加入jsonptest測試方法,下載地址:https://github.com/jaubourg/jquery-jsonp

[javascript] view plain copy
  1. <script type="text/javascript" src="jquery.jsonp.js"></script>  
  2. <script type="text/javascript">  
  3. function jsonptest(){  
  4. $.jsonp({  
  5.    url:'http://192.168.10.111/demo/testjson',  
  6.    data:{rel:13},  
  7.    callbackParameter:"callback",  
  8.    timeout:3000,  
  9.    dataFilter:function(json){  
  10.     console.log("jsonp.filter:"+json.name);  
  11.     json.name = "測試123435";  
  12. return json;  
  13. },  
  14.    success:function(json,textStatus,xOptions){  
  15.        console.log("jsonp.success:"+json.name);  
  16.    },  
  17.    error:function(xOptions,textStatus){  
  18.     console.log("jsonp.error:"+textStatus+", rel="+xOptions.data.rel);  
  19.    }  
  20. });  
  21. }  

再添加一個按鈕用來測試該js方法,如下:

[html] view plain copy
  1. <input type="button" value="jsonptest" onclick="jsonptest()"/>  

說明:點擊jsonptest按鈕後,控制檯打印出來的效果和使用$ajax方法時的基本一致,不同的是dataFilter方法:雖然二者都提供了dataFilter方法,但$.jsonp的dataFilter中數據已經直接轉換成json對象了,而$.ajax的dataFilter中獲取的卻是原生的帶callback方法名的json字符串(測試時控制檯打印出來的是undefined)。如果需要對返回的數據做預處理的話,建議使用jQuery-JSONP插件的$.jsonp方法

前面介紹了用servlet編寫testjson方法,假設你對nutz框架(http://www.nutzam.com/)熟悉的話,下面貼出使用nutz框架編寫testjson方法:

[java] view plain copy
  1. @At("/testjson")  
  2. @Ok("raw")  
  3. public String testjson(HttpServletRequest req, String callback, String rel) throws Exception {  
  4.     Map<String, String> jsonMap = new LinkedHashMap<String, String>();  
  5.     jsonMap.put("id""3");  
  6.     jsonMap.put("name""zhangsan");  
  7.     jsonMap.put("telephone""13612345678");  
  8.     jsonMap.put("rel", rel);  
  9.     String jsonp = callback + "(" + Json.toJson(jsonMap) + ")";  
  10.     return jsonp;  
  11. }  
注意:如果你在MainModule中設置了全局的返回類型爲json的話(@Ok("json")),那麼testjson方法上需要加上@Ok("raw")註解,不做解釋,不明白可以看nutz官方文檔。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章