jsonp跨域訪問的分析(前端和後端)

來源:互聯網
上載者:User

本篇文章給大家帶來的內容是關於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");            }        });

需要注意的地方是:

  • 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({            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)”的方式構造。

  • 如果要測試的話記得在跨域環境(兩台機器)下進行。

完整的樣本就是上面兩段代碼,親測有效。

相關關鍵詞:
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.