標籤:
json和jsonp的使用區別
一. 跨域請求的概念
JavaScript出於安全方面的考慮,不允許跨域調用其他頁面的對象。
二. json和jsonp
JSON是一種基於文本的資料交換方式(不支援跨域),而JSONP是一種非官方跨域資料互動協議。
使用json格式傳遞資料的用戶端代碼如下:
1 $(function () { 2 var user = { 3 "username": "HelloWorld" 4 }; 5 6 $.ajax({ 7 url: "http://localhost:8080/Changyou/UserInfo", 8 type: "POST", 9 contentType: "application/json; charset=utf-8",10 dataType: "json", //json不支援跨域請求,只能使用jsonp11 data: {12 user: JSON.stringify(user)13 },14 success: function (data) {15 $("#user_name")[0].innerHTML = data.user_name;16 $("#user_teleNum")[0].innerHTML = data.user_teleNum;17 $("#user_ID")[0].innerHTML = data.user_ID;18 },19 error: function () {20 alert("請求逾時錯誤!");21 }22 })23 });
然而,簡單地使用json並不能支援跨域資源請求,為瞭解決這個問題,需要採用jsonp資料互動協議。眾所周知,js檔案的調用不受跨域與否的限制,因此如果想通過純web端跨域訪問資料,只能在遠程伺服器上設法將json資料封裝進js格式的檔案中,供用戶端調用和進一步處理,這就是jsonp協議的原理。該協議的一個要點就是允許使用者傳遞一個callback參數給服務端,然後服務端返回資料時會將這個callback參數作為函數名來包裹住JSON資料,這樣用戶端就可以隨意定製自己的函數來自動處理返回資料了。
簡單的說,就是json不支援跨域,而js可以跨域,因此在伺服器端用用戶端提供的js函數名將json資料封裝起來,再將函數提供給用戶端調用,從而獲得json資料。
開發過程中,如果出現類似 “Origin ****** is not allowed by Access-Control-Allow-Origin.” 的錯誤,則可能是由於json資料不支援跨域導致的,應考慮使用jsonp協議。
如果出現類似 ”SyntaxError: Unexpected token ‘:‘. Parse error.“ 的錯誤,則可能是由於返回的json資料沒有用”callback“傳遞的函數名封裝導致的。
用戶端代碼如下:
1 $(function () { 2 3 var user = { 4 "username": "HelloWorld" 5 }; 6 7 $.ajax({ 8 url: "http://localhost:8080/Changyou/UserInfo", 9 type: "POST",10 contentType: "application/json; charset=utf-8",11 dataType: "jsonp", //json不支援跨域請求,只能使用jsonp12 data: {13 user: JSON.stringify(user)14 },15 jsonp: "callback", //傳遞給請求處理常式或頁面的,用以獲得jsonp回呼函數名的參數名,預設為callback16 jsonpCallback: "userHandler", //自訂的jsonp回呼函數名稱,預設為jQuery自動產生的隨機函數名,也可以寫"?",jQuery會自動為你處理資料17 success: function (data) {18 $("#user_name")[0].innerHTML = data.user_name;19 $("#user_teleNum")[0].innerHTML = data.user_teleNum;20 $("#user_ID")[0].innerHTML = data.user_ID;21 },22 error: function () {23 alert("請求逾時錯誤!");24 }25 })26 });
伺服器端代碼如下:
1 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 2 response.setContentType("application/json; charset=utf-8"); 3 String username = new String(request.getParameter("user").getBytes("ISO-8859-1"),"utf-8"); 4 String callback = new String(request.getParameter("callback").getBytes("ISO-8859-1"),"utf-8"); 5 System.out.println("接收到的資料:" + username); 6 System.out.println("callback的值:" + callback); 7 JSONObject user = JSONObject.fromObject(username); 8 System.out.println("接收到的使用者名稱:" + user.get("username")); 9 JSONObject userinfo = new JSONObject();10 userinfo.put("user_name", "張鳴曉");11 userinfo.put("user_teleNum", "18810011111");12 userinfo.put("user_ID", "123456789098765432");13 PrintWriter out = response.getWriter();14 String backInfo = callback + "(" + userinfo.toString() + ")"; //將json資料封裝在callback函數中提供給用戶端15 out.print(backInfo);16 out.close();17 }
儘管用戶端沒有實現userHandler函數,但也能成功運行,原因就是jquery在處理jsonp類型的ajax時,自動幫你產生回呼函數並把資料取出來供success屬性方法來調用。
更詳細解釋,參見http://kb.cnblogs.com/page/139725/
json和jsonp的使用區別