跨域JSONP原理及調用具體示例

上篇博客介紹了同源策略和跨域訪問概念,其中提到跨域常用的基本方式:JSONP和CORS。
  那這篇博客就介紹JSONP方式。
  JSONP原理
  在同源策略下,在某個服務器下的頁面是無法獲取到該服務器以外的數據的,但img、iframe、script等標籤是個例外,這些標籤可以通過src屬性請求到其他服務器上的數據。
  而JSONP就是通過script節點src調用跨域的請求。
  當我們通過JSONP模式請求跨域資源時,服務器返回給客戶端一段javascript代碼,這段javascript代碼自動調用客戶端回調函數。
  舉個例子
  客戶端http://localhost:8080訪問服務器http://localhost:11111/user,正常情況下,這是不允許的。因爲這兩個URL是不同域的。
  
  若我們使用JSONP格式發送請求的話?
  http://localhost:11111/user?callback=callbackfunction
  則服務器返回的數據如下:
  callbackfunction({"id":1,"name":"test"})
  仔細看看服務器返回的數據,其實就是一段javascript代碼,這就是函數名(參數)格式。
  服務器返回後,則自動執行callbackfunction函數。
  因此,客戶端需要callbackfunction函數,以便使用JSONP模式返回javascript代碼後自動執行其回調函數。

  注意:其中url地址中的callback和callbackfunction是隨意命名的。
  
  具體的JS實現JSONP代碼。

  JS中:

   

  1.   <script>  
  2.   var url = "http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction";   
  3.   var script = document.createElement('script');   
  4.   script.setAttribute('src', url);  //load javascript    
  5.   document.getElementsByTagName('head')[0].appendChild(script);   
  6.   
  7.   //回調函數  
  8.    function callbackfunction(data){  
  9. var html=JSON.stringify(data.RESULTSET);  
  10. alert(html);  
  11.      }  



  服務器代碼Action:
  後臺返回的json外面需要由回調函數包裹。具體的方法如下:
  
  1. public class TestJson extends ActionSupport{  
  2.   
  3.     @Override  
  4.     public String execute() throws Exception {  
  5.         try {  
  6.             JSONObject jsonObject=new JSONObject();  
  7.             List list=new ArrayList();  
  8.             for(int i=0;i<4;i++){  
  9.                 Map paramMap=new HashMap();  
  10.                 paramMap.put("bank_no", 100+i);  
  11.                 paramMap.put("money_type", i);  
  12.                 paramMap.put("bank_name", i);  
  13.                 paramMap.put("bank_type", i);  
  14.                 paramMap.put("bank_status", 0);  
  15.                 paramMap.put("en_sign_ways", 1);  
  16.                 list.add(paramMap);  
  17.             }  
  18.             JSONArray rows=JSONArray.fromObject(list);  
  19.             jsonObject.put("RESULTSET", rows);  
  20.             HttpServletRequest request=ServletActionContext.getRequest();  
  21.             HttpServletResponse response=ServletActionContext.getResponse();  
  22.             response.setContentType("text/javascript");  
  23.               
  24.               
  25.             boolean jsonP = false;  
  26.             String cb = request.getParameter("jsonp");  
  27.             if (cb != null) {  
  28.                 jsonP = true;  
  29.                 System.out.println("jsonp");  
  30.                 response.setContentType("text/javascript");  
  31.             } else {  
  32.                 System.out.println("json");  
  33.                 response.setContentType("application/x-json");  
  34.             }  
  35.             response.setCharacterEncoding("UTF-8");  
  36.             Writer out = response.getWriter();  
  37.             if (jsonP) {  
  38.                 out.write(cb + "("+jsonObject.toString()+")");  
  39.                 System.out.println(jsonObject.toString());  
  40.             }  
  41.             else{  
  42.                 out.write(jsonObject.toString());  
  43.                  System.out.println(jsonObject.toString());  
  44.             }  
  45.         } catch (Exception e) {  
  46.             e.printStackTrace();  
  47.         }  
  48.          
  49.         return null;  
  50.     }  
  51. }  
 
 JQUERY實現JSONP代碼。
 Jquery從1.2版本開始也支持JSONP的實現。
  1. $(function(){  
  2.      jQuery.getJSON("http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=?",function(data)  
  3. {   
  4.   var html=JSON.stringify(data.RESULTSET);  
  5. $("#testjsonp").html(html);  
  6. }  
  7.      );   
  8. });  
  第一個?代表後面是參數,與咱們一般調用一樣。重要的是第二個?,則是jquery動態給你生成毀掉函數名稱。

至於後臺代碼和上述一致,使用同一個後臺。

JQUERY中Ajax實現JSONP代碼。
  1.  $.ajax({  
  2. type:"GET",  
  3. async :false,  
  4. url:"http://localhost:8080/crcp/rcp/t99eidt/testjson.do",  
  5. dataType:"jsonp",  
  6. success:function(data){  
  7. var html=JSON.stringify(data.RESULTSET);  
  8. $("#testjsonp").html(html);  
  9. },  
  10. error:function(){  
  11. alert("error");  
  12. }  
  13.   
  14. });  
    注意:這種形式,默認的參數是callback,而不是會是其他。則action代碼中獲取calback值則
    String cb=request.getParameter("callback");
    並且生成的回調函數,默認也是類似上述一大串數字。
    根據Ajax手冊,更改callback名稱以及回調函數名稱。
    http://www.w3school.com.cn/jquery/ajax_ajax.asp 
    jsonpCallback:callbackfunction,則請求的地址爲:
    最後返回前臺的是:
    callbackfunction(具體的json值)

    其中上述JS實現JSONP代碼中,若不是動態拼接script腳本,而是直接寫script標籤,類似如下:
   <script type="text/javascript" src=""></script>
   若這樣寫的話,通過debug發現,的確正確返回了,但是一直提示找不到回調函數。即使js也提供了回調函數【各個瀏覽器都測試】
   若要通過JS來顯示,則通過代碼動態create script標籤。

   JSONP跨域方式,很方便,同時也支持大多部分瀏覽器,但是唯一缺點是,只支持GET提交方式,不支持其他POST提交。
   若url地址傳輸的參數過多,如何實現呢?下篇博客會講解另一種跨域方案CROS原理以及具體調用示例。
本文轉載自:http://blog.csdn.net/yuebinghaoyuan/article/details/32706277
發佈了27 篇原創文章 · 獲贊 5 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章