基于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); };