1. 程式人生 > >jQuery和java後臺的jsonp跨域問題

jQuery和java後臺的jsonp跨域問題

Jsonp原理:

  ajax本身是不可以跨域的,通過產生一個script標籤來實現跨域。因為script標籤的src屬性是沒有跨域的限制的。其實設定了dataType: ‘jsonp’後,$.ajax方法就和ajax XmlHttpRequest沒什麼關係了,取而代之的則是JSONP協議。JSONP是一個非官方的協議,它允許在伺服器端整合Script tags返回至客戶端,通過javascript callback的形式實現跨域訪問。
  
  JSONP是一種指令碼注入(Script Injection)行為,所以也有一定的安全隱患。首先在客戶端註冊一個callback (如:’jsoncallback’), 然後把callback的名字(如:jsonp1236827957501)傳給伺服器。注意:服務端得到callback的數值後,要用jsonp1236827957501(……)把將要輸出的json內容包括起來,此時,伺服器生成 json 資料才能被客戶端正確接收。

然後以 javascript 語法的方式,生成一個function , function 名字就是傳遞上來的引數 ‘jsoncallback’的值 jsonp1236827957501 .

最後將 json 資料直接以入參的方式,放置到 function 中,這樣就生成了一段 js 語法的文件,返回給客戶端。

客戶端瀏覽器,解析script標籤,並執行返回的 javascript 文件,此時javascript文件資料,作為引數,
傳入到了客戶端預先定義好的 callback 函式(如上例中jquery $.ajax()方法封裝的的success: function (json))裡.(動態執行回撥函式)

可以說jsonp的方式原理上和是一致的(qq空間就是大量採用這種方式來實現跨域資料交換的) .

頁面中js為:

$.ajax({
             url: "http://" + ipPort + "/user/getUser",
             type: 'GET',
             dataType: 'jsonp',
             jsonp: 'callback',                                
             success: function (data) {
                   alert('success:'
+data); }, fail: function () { alert('fail'); } });

java後臺中的程式碼為:

/**
 * 直接輸出.處理jsonp返回的資料
 */
public static void printJsonData(String text){
    PrintWriter print;
    try {
        HttpServletRequest request = ThreadContextHolder.getHttpRequest();
        HttpServletResponse response = ThreadContextHolder.getHttpResponse();
        response.setContentType("text/html;charset=utf-8");
        print=response.getWriter();
        String jsonp=request.getParameter("callback");//callback為回撥函式名,要和js名保持一致
        if(jsonp!=null){
            text=jsonp+"({\"data\":"+text+","+"\"token\":\""+StringUtil.token()+"\"})";
        }else{
            text="{\"data\":"+text+","+"\"token\":\""+StringUtil.token()+"\"}";
        }
        print.write(text);
        print.close();
    } catch (IOException e) {
        System.err.println(e.getMessage());
    }
}