1、什麼是跨域訪問
舉個栗子:在A網站中,咱們但願使用Ajax來得到B網站中的特定內容。若是A網站與B網站不在同一個域中,那麼就出現了跨域訪問問題。你能夠理解爲兩個域名之間不能跨過域名來發送請求或者請求數據,不然就是不安全的。跨域訪問違反了同源策略,同源策略的詳細信息能夠點擊以下連接:Same-origin_policy;
總而言之,同源策略規定,瀏覽器的ajax只能訪問跟它的HTML頁面同源(相同域名或IP)的資源。
2、什麼是JSONP
JSONP(JSON with Padding)是JSON的一種「使用模式」,可用於解決主流瀏覽器的跨域數據訪問的問題。
因爲同源策略,通常來講位於 server1.example.com 的網頁沒法與不是 server1.example.com的服務器溝通,而 HTML 的<script> 元素是一個例外。利用<script>元素的這個開放策略,網頁能夠獲得從其餘來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並非 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。更具體的原理須要更多篇幅的講解,小夥伴能夠自行去百度。前端
3、JSONP的使用
前端的使用示例
JQuery Ajax對JSONP進行了很好的封裝,咱們使用起來很方便。前端示例:jquery
$.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"); } });
須要注意的地方是:
dataType,該參數必需要設置成jsonp
jsonp,該參數的值須要與服務器端約定,詳細狀況下面介紹。(約定俗成的默認值爲callback)
後端的配合示例
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
4、總結
最終,先後端的相應代碼應該是這樣的:
前端json
$.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)+")"; }
須要注意的是:
前端注意與後端溝通約定jsonp的值,一般默認都是用callback。
後端根據jsonp參數名獲取到參數後要與原本要返回的json數據按「callback(json)」的方式構造。
若是要測試的話記得在跨域環境(兩臺機器)下進行。
完整的示例就是上面兩段代碼,這裏就不提供Github鏈接了。上面的示例親測有效,若是有遇到問題的,歡迎留言提問。
原文:https://blog.csdn.net/zhoucheng05_13/article/details/78694766?utm_source=copy跨域