extJs中通過jQuery的ajax進行跨域(即jsonp進行跨域)獲取數據

 這幾天, 工作有一新需求, 要求前端extJs頁面通過ajax獲取另一個項目中的數據並展示出來, 後來發現如果直接在store中使用普通的方法獲取數據後臺服務沒有響應, 總是報錯, 最後發現原來是同源策略在作怪,我們知道,JavaScript或jQuery是在Web前端開發中經常使用的動態腳本技術。在JavaScript中,有一個很重要的安全性限制,被稱爲“Same- Origin Policy”(同源策略)。這一策略對於JavaScript代碼能夠訪問的頁面內容做了很重要的限制,即JavaScript只能訪問與包含它的文檔或腳本 在同一域名下的內容。不同域名下的腳本不能互相訪問,即便是子域也不行。關於同源策略,讀者可百度更詳細的解釋,這裏不再贅述。
 針對這一現象,採用JSONP跨域GET請求是一個常用的解決方案,下面我們來看一下JSONP跨域是如何實現的,並探討下JSONP跨域的原理.
 我們知道,由於同源策略的限制,XmlHttpRequest只允許請求當前源(域名、協議、端口)的資源。若要跨域請求出於安全性考慮是不行的,但是我們發現,Web頁面上調用js文件時則不受是否跨域的影響,而且擁有”src”這個屬性的標籤都擁有跨域的能力,比如<script>、<img>、<iframe>,這時候,聰明的程序猿就想到了變通的方法,如果要進行跨域請求, 通過使用html的script標記來進行跨域請求,並在響應中返回要執行的script代碼,其中可以直接使用JSON傳遞 javascript對象。即在跨域的服務端生成JSON數據,然後包裝成script腳本回傳,這樣就突破同源策略的限制,解決了跨域訪問的問題。
 具體實現如下:
 前端代碼:
    $.ajax({
        dataType:"jsonp",
        jsonp: "jsoncallback",//傳遞給請求處理程序,用以獲得jsonp回調函數名的參數名(默認爲:callback)
        jsonpCallback:"success_jsonpCallback",//自定義的jsonp回調函數名稱,默認爲jQuery自動生成的隨機函數名
        url:"http://localhost:8082/elasticSearchTest/test.do?jsoncallback=?", //跨域請求的URL
        method:"GET",  // jquey是不支持post方式跨域的
        success:function(data){}//成功獲取跨域服務器上的json數據後,會動態執行這個callback函數
    });
//因爲直接在ext中放入數據無法使用jquery的ajax方法, 可以先跨域獲取數據, 然後在將獲得的數據load進去. 具體如下:
function success_jsonpCallback(data){
    examination.grid.getStore().loadData(data);

}
服務器端代碼:
    @RequestMapping(value = "/test.do")
    @ResponseBody
    public void selectAllDatas(HttpServletRequest request,HttpServletResponse response) {
        try {
            response.setHeader("Access-Control-Allow-Origin", "*");
        //根據html指定的jsonp回調函數的參數名,獲取回調函數的名稱
        //callbackName的值其實就是:success_jsonpCallback
            String callBackName =(String)request.getAttribute("jsoncallback");
            callBackName=request.getParameter("jsoncallback");

            String jsonStr = "{\"name\":\"張三\",\"age\":28}";
            String renderStr = callBackName+"("+jsonStr+")"; //最終返回的數據爲:success_jsonpCallback({"name":"張三","age":28})

             response.setContentType("text/plain;charset=UTF-8");
             response.getWriter().write(renderStr);
             response.getWriter().flush();
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

jsonp的原理:

首先在客戶端註冊一個callback (如:’jsoncallback’), 然後把callback的名字(如:success_jsonpCallback)傳給服務器端對應的處理函數。

服務器先生成需要返回給客戶端的 json 數據。然後以 javascript 語法的方式,生成一個function , function 名字就是傳遞上來的參數(jsoncallback)的值(success_jsonpCallback) 。

最後將 json 數據直接以入參的方式,放置到 function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端。
客戶端瀏覽器,解析script標籤,並將服務器端返回的數據,作爲參數,
傳入到了客戶端預先定義好的 callback 函數(如上例中jquery $.ajax()方法封裝的的success: function (json))裏。

實際上跨域是通過動態增加script來加載數據,無法直接獲得數據,所以需要使用回調函數。

本文參考: 本文參考了此文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章