標籤:err school create 後台 使用 use == servlet jsonp
上篇部落格介紹了同源策略和跨域訪問概念,當中提到跨域經常使用的基本方式:JSONP和CORS。
那這篇部落格就介紹JSONP方式。
JSONP原理 在同源策略下,在某個server下的頁面是無法擷取到該server以外的資料的,但img、iframe、script等標籤是個例外。這些標籤能夠通過src屬性請求到其它server上的資料。 而JSONP就是通過script節點src調用跨域的請求。 當我們通過JSONP模式請求跨域資源時,server返回給client一段javascript代碼,這段javascript代碼自己主動調用client回呼函數。 舉個範例 clienthttp://localhost:8080訪問serverhttp://localhost:11111/user。正常情況下,這是不同意的。
由於這兩個URL是不同域的。
若我們使用JSONP格式發送請求的話? http://localhost:11111/user?
callback=callbackfunction 則server返回的資料例如以下: callbackfunction({"id":1,"name":"test"}) 細緻看看server返回的資料,事實上就是一段javascript代碼。這就是函數名(參數)格式。 server返回後,則自己主動運行callbackfunction函數。 因此,client須要callbackfunction函數。以便使用JSONP模式返回javascript代碼後自己主動運行其回呼函數。
注意:當中url地址中的callback和callbackfunction是任意命名的。
詳細的JS實現JSONP代碼。
JS中:
<script> var url = "http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction"; var script = document.createElement('script'); script.setAttribute('src', url); //load javascript document.getElementsByTagName('head')[0].appendChild(script); //回呼函數 function callbackfunction(data){var html=JSON.stringify(data.RESULTSET);alert(html); } </script>
server代碼Action: 後台返回的json外面須要由回呼函數包裹。詳細的方法例如以下:
public class TestJson extends ActionSupport{@Overridepublic String execute() throws Exception {try {JSONObject jsonObject=new JSONObject();List list=new ArrayList();for(int i=0;i<4;i++){Map paramMap=new HashMap();paramMap.put("bank_no", 100+i);paramMap.put("money_type", i);paramMap.put("bank_name", i);paramMap.put("bank_type", i);paramMap.put("bank_status", 0);paramMap.put("en_sign_ways", 1);list.add(paramMap);}JSONArray rows=JSONArray.fromObject(list);jsonObject.put("RESULTSET", rows);HttpServletRequest request=ServletActionContext.getRequest();HttpServletResponse response=ServletActionContext.getResponse();response.setContentType("text/javascript");boolean jsonP = false;String cb = request.getParameter("jsonp");if (cb != null) { jsonP = true; System.out.println("jsonp"); response.setContentType("text/javascript");} else {System.out.println("json"); response.setContentType("application/x-json");}response.setCharacterEncoding("UTF-8");Writer out = response.getWriter();if (jsonP) { out.write(cb + "("+jsonObject.toString()+")"); System.out.println(jsonObject.toString());}else{out.write(jsonObject.toString()); System.out.println(jsonObject.toString());}} catch (Exception e) {e.printStackTrace();} return null;}}
JQUERY實現JSONP代碼。
Jquery從1.2版本號碼開始也支援JSONP的實現。
$(function(){ jQuery.getJSON("http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=?",function(data){ var html=JSON.stringify(data.RESULTSET);$("#testjsonp").html(html);} ); });
第一個?代表後面是參數,與咱們一般調用一樣。重要的是第二個?。則是jquery動態給你產生毀掉函數名稱。
至於後台代碼和上述一致,使用同一個後台。
JQUERY中Ajax實現JSONP代碼。
$.ajax({ type:"GET", async :false, url:"http://localhost:8080/crcp/rcp/t99eidt/testjson.do", dataType:"jsonp", success:function(data){ var html=JSON.stringify(data.RESULTSET); $("#testjsonp").html(html); }, error:function(){ alert("error"); } });
注意:這樣的形式,預設的參數是callback,而不是會是其它。則action代碼中擷取calback值則 String cb=request.getParameter("callback"); 而且產生的回呼函數,預設也是類似上述一大串數字。 依據Ajax手冊。更改callback名稱以及回呼函數名稱。
http://www.w3school.com.cn/jquery/ajax_ajax.asp jsonp:jsonp,則請求的地址為:
jsonp=%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E5%90%8D">http://localhost:8080/crcp/rcp/t99eidt/testjson.do?
jsonp=自己主動產生回呼函數名 jsonpCallback:callbackfunction,則請求的地址為: http://localhost:8080/crcp/rcp/t99eidt/testjson.do?
jsonp=callbackfunction 最後返回前台的是: callbackfunction(詳細的json值)
當中上述JS實現JSONP代碼中。若不是動態拼接script指令碼,而是直接寫script標籤。類似例如以下: <script type="text/javascript" src=""></script> 若這樣寫的話,通過debug發現,的確正確返回了。可是一直提示找不到回呼函數。即使js也提供了回呼函數【各個瀏覽器都測試】 若要通過JS來顯示。則通過代碼動態create script標籤。
JSONP跨域方式。非常方便,同一時候也支援大多部分瀏覽器,可是唯一缺點是,僅僅支援GET提交方式,不支援其它POST提交。 若url地址傳輸的參數過多,怎樣實現呢?下篇部落格會解說還有一種跨域方案CROS原理以及詳細調用示範範例。
跨域JSONP原理及調用詳細示範範例