基於jQuery的ajax對WebApi和OData的封裝
WebApi 的使用帶來了一個顯著的特點,對type有一定的要求。一般ajax的type無非就是兩種,GET和POST。如果用JSONP來跨域的話,就只能用GET。但是現在WebApi來了,type的類型增加了一倍還要多。這個雖說問題不大,就是多個put、delete,看看要求掌握一下就可以了。但是我覺得,這個總是要有個過程,另外寫代碼的時候還要想想是put還是post,萬一寫錯了,就會帶來不必要的麻煩。那么能不能封裝一下呢?
jQuery的ajax使用其實已經很簡單了,但是還是需要設置幾個參數,那么能不能在簡潔一點呢?或者說有沒有必要在封裝一下?
這個就是仁者見仁智者見智的問題了,另外還要看環境,看需求。簡單的需求確實沒有必要再次封裝,直接用就好了。如果需求復雜了一點,那么封裝一下也是有必要的。
我們還是先來看看要求
1、 WebApi對type有要求。
2、 OData有自己的使用方式和語法格式。
在看看目標:
1、 使用簡單。
2、 便於更改。
3、 便於更換。
WebApi 剛才說過了,OData呢,確實很強大也很靈活,只是太靈活了,導致增加了學習成本和時間,那么能不能也封裝一下,變成大家熟悉的方式呢?
思路
可能有人看到這個圖后回想:我k,用得着這么復雜嗎?過度設計吧。其實這個看個人的經歷了,經歷過的就很容易理解,沒經歷過的就會很奇怪。最近在看清培兄的大作,就覺得挺奇怪,為啥要這么設計呢?其實是我沒有那樣的經歷,也許以后就理解了吧。
封裝方式
公用屬性的封裝,就要看實際需求了,比如我的項目里需要對租戶ID進行處理,對head里的Authorization的處理(存儲token)、cors跨域的處理,訪問成功后的統一處理,失敗后的統一處理等。
查詢的封裝,這個就比較復雜一點,因為有OData,要對他的語法有一個通用的“翻譯”,讓不會OData的人也能夠快速掌握。最后達到,讓人感覺不到有OData的存在。這樣做便於切換,OData是很強大,但是並不意味着一定會一直使用OData,哪天不用了,客戶端的調用代碼總不能也跟着大變臉。由於剛剛接觸OData,所以封裝也是剛剛開始嘗試,肯定很多不完善的地方,感覺大家的多多指教!謝過了先。
添加和修改的封裝就比較簡單了,設置好type也就沒啥事情了,然后可以根據自己的實際情況加點輔助功能,比如設置ID,設置租戶ID等。
刪除呢,看着簡單,但是實際上是相當的復雜。簡單的說,提交一個請求就完事了;復雜的說呢,是物理刪除還是邏輯刪除,刪除前要不要做數據完整性的判斷,要不要做級聯刪除。目前呢只是簡單的封裝了一下。
這次封裝,時間比較緊迫,另外對新項目的理解還不夠,比如api的路由規律還沒有掌握,本來還想封裝一下URL,但是只能暫時放棄了。
1 //對ajax的封裝 //最基礎的一層封裝 2 Nature.Ajax = function(ajaxInfo) { 3 4 //定義默認值 5 //type: "GET", //訪問方式。 6 //dataType: Nature.AjaxConfig.ajaxDataType, //數據類型:JSON、JSONP、text 7 //cache: true, //是否緩存,默認緩存 8 //urlPara: {},//url后面的參數。一定會加在url后面,不會加到form里。 9 //formData: {},//表單里的參數。如果dataType是JSON,一定加在form里,不會加在url后面;如果dataType是JSONP的話,只能加在url后面。 10 //url: //依靠上層指定 11 12 //補全ajaxInfo 13 //cache 14 if (typeof ajaxInfo.cache == "undefined") ajaxInfo.cache = false; 15 16 //type 17 if (typeof ajaxInfo.formData == "undefined") { 18 //ajaxInfo.type = "GET"; 19 } else { 20 //ajaxInfo.type = "POST"; 21 ajaxInfo.data = ajaxInfo.formData; 22 } 23 24 //處理URL和參數 25 if (typeof ajaxInfo.url != "undefined") { 26 //var tmpUrlPara = ""; 27 //var para = ajaxInfo.urlPara; 28 //for (var key in para) { 29 // tmpUrlPara += "&" + key + "=" + para[key]; 30 //} 31 32 //if (ajaxInfo.url.indexOf('?') >= 0) { 33 // //原地址有參數,直接加 34 // ajaxInfo.url += tmpUrlPara; 35 //} else { 36 // //原地址沒有參數,變成?再加 37 // ajaxInfo.url += tmpUrlPara.replace('&', '?'); 38 //} 39 40 ajaxInfo.url = top.apiUrl + ajaxInfo.url.replace(/{TenantId}/g, top.tenantId); 41 42 } 43 44 //處理 beforeSend 45 var beforeSend = ajaxInfo.beforeSend; 46 47 ajaxInfo.beforeSend = function (XMLHttpRequest) { 48 if (typeof beforeSend == "function") 49 beforeSend(token); 50 51 XMLHttpRequest.setRequestHeader("Authorization", "Bearer " + top.token); 52 } 53 54 //處理xhrFields 55 if (typeof ajaxInfo.xhrFields == "undefined") { 56 ajaxInfo.xhrFields = { 57 //允許cors跨域訪問時添加cookie 58 withCredentials: true 59 }; 60 } else { 61 if (typeof ajaxInfo.xhrFields.withCredentials == "undefined") { 62 ajaxInfo.xhrFields.withCredentials = true; 63 } 64 } 65 //使用cors的方式實現跨域 66 jQuery.support.cors = true; 67 68 //處理error 69 var error = ajaxInfo.error; 70 ajaxInfo.error = function(request, textStatus, errorThrown) { 71 //訪問失敗,自動停止加載動畫,並且給出提示 72 //獲取返回的錯誤提示 73 74 var errMsg = request.responseText; 75 if (typeof errMsg != "undefined") { 76 errMsg = eval("(" + errMsg + ")"); 77 errMsg = errMsg.message; 78 } 79 alert("提交" + ajaxInfo.title + "的時候發生錯誤!\r\n<br>" + errMsg); 80 if (typeof top.spinStop == "function") 81 top.spinStop(); 82 if (typeof error == "function") error(); 83 }; 84 85 //處理success 86 var success = ajaxInfo.success; 87 ajaxInfo.success = function(data) { 88 //顯示調試信息 89 //if (typeof parent.DebugSet != "undefined") 90 // parent.DebugSet(data.debug); 91 92 if (typeof success == "function") 93 success(data); 94 95 }; 96 97 //開始執行ajax 98 $.ajax(ajaxInfo); 99 100 101 };
1 //查詢數據 2 Nature.Ajax.find = function (ajaxInfo) { 3 ajaxInfo.type = "GET"; 4 var info = ajaxInfo.pagerInfo ; 5 //處理url,分頁和查詢 6 if (typeof info != "undefined") { 7 if (typeof ajaxInfo.data == "undefined") ajaxInfo.data = {}; 8 9 if (typeof info.pageSize != "undefined") 10 ajaxInfo.data["$top"] = info.pageSize; 11 12 if (typeof info.pageIndex != "undefined") 13 ajaxInfo.data["$skip"] = (info.pageIndex - 1) * info.pageSize; 14 15 if (typeof info.orderby != "undefined" && info.orderby != "") 16 ajaxInfo.data["$orderby"] = info.orderby; 17 18 } 19 20 //處理查詢條件 21 22 23 24 //處理返回事件 $orderby 25 var success = ajaxInfo.success; 26 27 ajaxInfo.success = function (data) { 28 // 29 //判斷返回信息 30 if (typeof data.message != "undefined") { 31 alert(data.message); 32 } else { 33 if (typeof success == "function") 34 success(data); 35 } 36 }; 37 38 Nature.Ajax(ajaxInfo); 39 40 };
//添加數據 Nature.Ajax.add = function(ajaxInfo) { ajaxInfo.type = "POST"; //判斷data 。添加 id 和tenantId。 if(typeof ajaxInfo.data != "undefined"){ if(typeof ajaxInfo.data.id != "undefined"){ ajaxInfo.data.id = '00000000000000000000000000000000'; } if(typeof ajaxInfo.data.tenantId != "undefined"){ ajaxInfo.data.tenantId = top.tenantId; } } Nature.Ajax(ajaxInfo); }; //修改數據 Nature.Ajax.update = function(ajaxInfo) { ajaxInfo.type = "PUT"; //判斷data 。添加 tenantId。 if(typeof ajaxInfo.data != "undefined"){ if(typeof ajaxInfo.data.tenantId != "undefined"){ ajaxInfo.data.tenantId = top.tenantId; } } Nature.Ajax(ajaxInfo); }; //刪除數據 Nature.Ajax.del = function(ajaxInfo) { ajaxInfo.type = "DELETE"; Nature.Ajax(ajaxInfo); };