以前寫過一篇 先定一個小目標,本身封裝個ajax,是基於原生js的,也就是jquery中ajax的簡化版本實現的思路。衆所周知,jquery的ajax是項目中最經常使用的請求後臺的方式,也算是封裝的很完美的api了,然而漸漸的咱們會發現,其實還能夠根據實際項目須要更優雅的進行一層封裝,先看調用方式:
html
熟悉EasyUI的猿們可能會以爲這種方式有點熟悉,沒錯,我就是看easyUI獲得的啓發,也顯然這樣的方式更利於前端作判斷,邏輯更清晰明瞭。那麼代碼後面是怎樣封裝的呢,我這裏貼出核心的代碼以及思路。前端
將後臺返回的不一樣業務狀態碼以函數回調的形式代替,減小if的多層級判斷。同時將通用的錯誤狀態碼邏輯(如這裏的900狀態是通用異常)、通用的請求參數(如client客戶端來源,是否須要token證書)、請求前置觸發操做(如加載中動畫)等等進行統一處理,既減小的代碼量,同時又更利於維護。java
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對象傳進去。jquery
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('已點贊'); } })
@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方法來自 ApiUtilgit
同時跨域也能夠參考之前的文章 jsonp跨域請求github