封裝ajax,含跨域

jquery的ajax是項目中最常用的請求後臺的方式,也算是封裝的很完美的api了,然而漸漸的我們會發現,其實還可以根據實際項目需要更優雅的進行一層封裝,先看調用方式:
834823-20170713114922056-778010018.png

熟悉EasyUI的猿們可能會覺得這種方式有點熟悉,沒錯,我就是看easyUI得到的啓發,也顯然這樣的方式更利於前端做判斷,邏輯更清晰明瞭。那麼代碼後面是怎樣封裝的呢,我這裏貼出核心的代碼以及思路。

思路

將後臺返回的不同業務狀態碼以函數回調的形式代替,減少if的多層級判斷。同時將通用的錯誤狀態碼邏輯(如這裏的900狀態是通用異常)、通用的請求參數(如client客戶端來源,是否需要token證書)、請求前置觸發操作(如加載中動畫)等等進行統一處理,既減少的代碼量,同時又更利於維護。

封裝的js代碼

var LI = {    //發送get請求
    GET: function(options){        this.ajax(options,'get');
    },    //發送post請求
    POST: function(options){        this.ajax(options,'post');
    },
    ajax: function(options,type){        var opts = {
            isCommonBefore: true, //默認是通用的加載中動畫
            client: 1, //TODO這裏應該根據內核判斷
            isCors: false,//默認不跨域
            isLogin: false
        }
        
        $.extend(true, options, opts || {});        
        //跨域,將請求地址 和 請求參數 都作爲參數傳遞調用後臺固定的跨域接口
        if (opts.isCors) {
            opts.data = {
                url: opts.url,//真實的url
                params: JSON.stringify(opts.data), //請求參數
            }
            opts.url = URL.CORS;
        }        
        //添加默認的參數
        opts.data.client = opts.client;        //需要登錄認證的請求
        if(opts.isLogin){
            opts.data.token = LI.getToken()
        }
        
        $.ajax({
            url: opts.url,
            data: opts.data,
            type: type,            async: opts.async,
            beforeSend: function() {
                opts.isCommonBefore ? LI.loadingShow() : (opts.beforeSend && opts.beforeSend())
            },
            success: function(json) {                if(json){                    console.log(opts.baseUrl || opts.url,' ajax is successful',json);
                    opts.success && opts.success(json);                    if(opts[json.status]){//區分不同的狀態碼回調函數
                        console.log(opts.baseUrl || opts.url,'ajax status is', json.status, '並已回調'+ json.status +'方法');                        eval(opts[json.status])(json);
                    }
                }else{                    console.error(opts.baseUrl || opts.url,'ajax 數據返回格式異常');
                    LI.ajaxError();
                }
            },
            error: function(){                console.error(opts.baseUrl || opts.url,' ajax is error');
                opts.error != undefined ? opts.error() : LI.commonError();
            },
            complete: function(XMLHttpRequest, textStatus) {                console.log(opts.baseUrl || opts.url,' ajax is complete');
            },
            timeout: opts.timeout || 20000
        })
    }
}

核心是這一句 eval(opts[json.status])(json); 將狀態碼轉換成回調函數,並將json對象傳進去。

調用

LI.POST({
    url: LI_ENV.URL.BASE + LI_ENV.API.doPrayerSquareLike,
    data: {
        prayerSquareId: LI.getUrlParameter('id')
    },
    isLogin: true,    //isCors: true,//如跨域設置true即可
    600: function(json){        console.log("點贊成功");
    },    803: function(){        console.log('請登錄後操作');
    },    609: function(){        console.log('已點贊');
    }
})

跨域Controller

@RequestMapping(value = "cors", method = {RequestMethod.GET,RequestMethod.POST})
@ResponseBody
public commonResult cors(@RequestParam String url,
                       @RequestParam(required=false) String params,
                       HttpServletRequest request, 
                       HttpServletResponse response) throws IOException, URISyntaxException {
    LOGGER.info("The request of cors,url:{},params:{}",url,params);
    boolean isGet = request.getMethod().toLowerCase().equals("get");    Map<String, String> map = new HashMap<String, String>();    if (!StringUtils.isBlank(params)) {        //有序遍歷
        LinkedHashMap<String, String> jsonMap = JSON.parseObject(params, new TypeReference<LinkedHashMap<String, String>>() {
        });        for (Map.Entry<String, String> entry : jsonMap.entrySet()) {
            map.put(entry.getKey(), entry.getValue());
        }
    }    
    String result = null;    try {        
        if (isGet) {
            result = apiService.doGet(MANAGE_URL + url, map);
        }else{
            HttpResult hr = apiService.doPost(MANAGE_URL + url, map);
            result = hr.getData();
        }
        
        JSONObject obj = JSONObject.parseObject(result);        
        try {
            Integer status = obj.getInteger("status");            String msg = obj.getString("msg");            return new commonResult(status, msg, obj.get("data"));
        } catch (Exception e) {            return commonResult.fail();
        }
    } catch (Exception e) {        return commonResult.fail();
    }
}

核心代碼如上,得到前端傳上來的url,以及解析params,再通過httpClient的形式請求真正的後臺地址,其中doPost方法來自 ApiUtil



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