本篇文章給大家帶來的內容是關於jsonp跨域訪問的分析(前端和後端),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所協助。
一、什麼是跨域訪問
舉個栗子:在A網站中,我們希望使用Ajax來獲得B網站中的特定內容。如果A網站與B網站不在同一個域中,那麼就出現了跨域訪問問題。你可以理解為兩個網域名稱之間不能跨過網域名稱來發送請求或者請求資料,否則就是不安全的。跨域訪問違反了同源策略,同源策略的詳細資料可以點擊如下連結:Same-origin_policy;
總而言之,同源策略規定,瀏覽器的ajax只能訪問跟它的HTML頁面同源(相同網域名稱或IP)的資源。
二、什麼是JSONP
JSONP(JSON with Padding)是JSON的一種“使用模式”,可用於解決主流瀏覽器的跨域資料訪問的問題。
由於同源策略,一般來說位於 server1.example.com 的網頁無法與不是 server1.example.com的伺服器溝通,而 HTML 的<script>
元素是一個例外。利用<script>
元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。更具體的原理需要更多篇幅的講解,小夥伴可以自行去百度。
三、JSONP的使用
前端的使用樣本
JQuery Ajax對JSONP進行了很好的封裝,我們使用起來很方便。前端樣本:
$.ajax({ type:"GET", url:"http://www.deardull.com:9090/getMySeat", //訪問的連結 dataType:"jsonp", //資料格式設定為jsonp jsonp:"callback", //Jquery產生驗證參數的名稱 success:function(data){ //成功的回呼函數 alert(data); }, error: function (e) { alert("error"); } });
需要注意的地方是:
後端的配合樣本
JQuery Ajax Jsonp原理
後端要配合使用jsonp,那麼首先得瞭解Jquery Ajax jsonp的一個特點:
Jquery在發送一個Ajax jsonp請求時,會在訪問連結的後面自動加上一個驗證參數,這個參數是Jquery隨機產生的,例如連結
http://www.deardull.com:9090/getMySeat?callback=jQuery31106628680598769732_1512186387045&_=1512186387046
中,參數callback=jQuery31106628680598769732_1512186387045&_=1512186387046
就是jquery自動添加的。
添加這個參數的目的是唯一標識這次請求。當伺服器端接收到該請求時,需要將該參數的值與實際要返回的json值進行構造(如何構造下面講解),並且返回,而前端會驗證這個參數,如果是它之前發出的參數,那麼就會接收並解析資料,如果不是這個參數,那麼就拒絕接受。
需要特別注意的是這個驗證參數的名字(我在這個坑上浪費了2小時),這個名字來源於前端的jsonp參數的值。如果把前端jsonp參數的值改為“aaa”,那麼相應的參數就應該是
aaa=jQuery31106628680598769732_1512186387045&_=1512186387046
後端接收與處理
知道了Jquery Ajax Jsonp的原理,也知道了需要接受的參數,我們就可以來編寫伺服器端程式了。
為了配合json,伺服器端需要做的事情可以概括為兩步:
第一步、接收驗證參數
根據與前端Ajax約定的jsonp參數名來接收驗證參數,樣本如下(使用SpringMVC,其他語言及架構原理類似)
@ResponseBody @RequestMapping("/getJsonp") public String getMySeatSuccess(@RequestParam("callback") String callback){
第二步、構造參數並返回
將接收的的驗證參數callback與實際要返回的json資料按“callback(json)”的方式構造:
@ResponseBody @RequestMapping("/getMySeat") public String getMySeatSuccess(@RequestParam("callback") String callback){ Gson gson=new Gson(); //google的一個json工具庫 Map<String,String> map=new HashMap<>(); map.put("seat","1_2_06_12"); return callback+"("+gson.toJson(map)+")"; //構造傳回值 }
四、總結
最終,前後端的相應代碼應該是這樣的:
前端
$.ajax({ type:"GET", url:"http://www.deardull.com:9090/getMySeat", //訪問的連結 dataType:"jsonp", //資料格式設定為jsonp jsonp:"callback", //Jquery產生驗證參數的名稱 success:function(data){ //成功的回呼函數 alert(data); }, error: function (e) { alert("error"); } });
後端
@ResponseBody @RequestMapping("/getMySeat") public String getMySeatSuccess(@RequestParam("callback") String callback){ Gson gson=new Gson(); Map<String,String> map=new HashMap<>(); map.put("seat","1_2_06_12"); logger.info(callback); return callback+"("+gson.toJson(map)+")"; }
需要注意的是:
完整的樣本就是上面兩段代碼,親測有效。