75.json和jsonp的區別?
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不支援跨域請求,只能使用jsonp 11 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不支援跨域請求,只能使用jsonp 12 data: { 13 user: JSON.stringify(user) 14 }, 15 jsonp: "callback", //傳遞給請求處理程式或頁面的,用以獲得jsonp回撥函式名的引數名,預設為callback 16 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屬性方法來呼叫。