情境:項目中我負責後台介面開發,介面提供給app端的開發人員。app端ajax遠程請求伺服器時會出現ajax跨域問題。由於我是第一次開發 以前也沒碰到過。所以我又上網查了文章,最後大致知道了實現方式。雖然不太瞭解原理。但是也解決了這個問題,所以記錄一下,方便自己以後複習。
思路:ajax請求後台時,在dataType的屬性寫上'jsonp',然後增加一個新的屬性:jsonp,屬性值為任一字元(比如jsonpCallback),在後台
可以用這個字元名接到一個值,而這個值在後台資料返回的時候要用到。因為用jsonp返回資料時的格式和普通返回不一樣。jsonp 返回資料的格式是要返回一個類似js函數的格式 但是沒有{},而你要返回的資料就放在參數中,具體的格式是:函數名(後台要傳輸的資料),這裡的函數名就是‘jsonpCallback’所接到的實際參數,後台傳輸的資料就是自己要返回的資料,比如ajax請求時,後台接到的‘jsonpCallback’的值是"1223541_js",你後台要返回你資料是個名叫dataList的集合。 然後 你可以後台拼接成上述格式 最終返回為這樣格式的: 1223541_js(‘dataList’) ,就可以了。
注意:①為什麼要用jsonp屬性的傳入後台參數的值做返回函數的函數名。 :因為 每個ajax都會產生不同的隨機字元,用隨機字元做傳回值,這樣可以找到是哪個ajax發出的請求。
② ()裡是要返回的參數,但必須拼接上單引號,使其作為變數參數回傳。
前台ajax的格式如圖:
上面是前台的請求格式,其實和普通的ajax沒有區別,就是dataType值變成了jsonp,然後多了個屬性:jsonp 屬性值可以隨便寫。當ajax請求後台時,後台根據jsonp中的字串名擷取真正的值 然後拼接 再作返回。返回的值就在回呼函數的參數中。然後就可以像普通ajax的操作一樣了。
後台代碼:
//代碼不全還有許多註解沒有加 但是不影響操作 public class TestJsonpAction{ //前台請求時進入的方法 public String getLogisticsStatusList () { String jsonpCallback = getParameter("jsonpCallback");//接收ajax請求的參數。 ……//接收的其他資料 還有其他處理的代碼 List<Map> result = page.getResult();//後台要返回的資料 String resultDate = JSONObject.fromObject(results).toString();//將資料轉成json格式(項目需要) //由於每次都要拼接資料所以把拼接部分寫成工具類,此處調用。(下方有工具類代碼) String callBackData= JsonUtil.getJsonCallBackString( resultDate , jsonpCallback);//調用工具類拼接成jspon需要的格式 Struts2Utils.renderJson( callBackData ); //最終返回前台的資料 }}
拼接格式的工具類:
package com.nebula.app.app.common.utils;public class JsonUtil {/** * @param str 要回傳前台的資料 * * @param jsonpCallback 前台接收的jsonp傳遞的值 * * */public static String getJsonCallBackString(String str ,String jsonpCallback){if(jsonpCallback == null ||"".equals(jsonpCallback)){return str;}else{return jsonpCallback+"('"+str+"')";} } }
大神的部落格 裡面有專業的介紹