基于jQuery的ajax对WebApi和OData的封装
基于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,但是只能暂时放弃了。
//对ajax的封装 //最基础的一层封装
Nature.Ajax = function(ajaxInfo) { //定义默认值
//type: "GET", //访问方式。
//dataType: Nature.AjaxConfig.ajaxDataType, //数据类型:JSON、JSONP、text
//cache: true, //是否缓存,默认缓存
//urlPara: {},//url后面的参数。一定会加在url后面,不会加到form里。
//formData: {},//表单里的参数。如果dataType是JSON,一定加在form里,不会加在url后面;如果dataType是JSONP的话,只能加在url后面。
//url: //依靠上层指定 //补全ajaxInfo
//cache
if (typeof ajaxInfo.cache == "undefined") ajaxInfo.cache = false; //type
if (typeof ajaxInfo.formData == "undefined") {
//ajaxInfo.type = "GET";
} else {
//ajaxInfo.type = "POST";
ajaxInfo.data = ajaxInfo.formData;
} //处理URL和参数
if (typeof ajaxInfo.url != "undefined") {
//var tmpUrlPara = "";
//var para = ajaxInfo.urlPara;
//for (var key in para) {
// tmpUrlPara += "&" + key + "=" + para[key];
//} //if (ajaxInfo.url.indexOf('?') >= 0) {
// //原地址有参数,直接加
// ajaxInfo.url += tmpUrlPara;
//} else {
// //原地址没有参数,变成?再加
// ajaxInfo.url += tmpUrlPara.replace('&', '?');
//} ajaxInfo.url = top.apiUrl + ajaxInfo.url.replace(/{TenantId}/g, top.tenantId); } //处理 beforeSend
var beforeSend = ajaxInfo.beforeSend; ajaxInfo.beforeSend = function (XMLHttpRequest) {
if (typeof beforeSend == "function")
beforeSend(token); XMLHttpRequest.setRequestHeader("Authorization", "Bearer " + top.token);
} //处理xhrFields
if (typeof ajaxInfo.xhrFields == "undefined") {
ajaxInfo.xhrFields = {
//允许cors跨域访问时添加cookie
withCredentials: true
};
} else {
if (typeof ajaxInfo.xhrFields.withCredentials == "undefined") {
ajaxInfo.xhrFields.withCredentials = true;
}
}
//使用cors的方式实现跨域
jQuery.support.cors = true; //处理error
var error = ajaxInfo.error;
ajaxInfo.error = function(request, textStatus, errorThrown) {
//访问失败,自动停止加载动画,并且给出提示
//获取返回的错误提示 var errMsg = request.responseText;
if (typeof errMsg != "undefined") {
errMsg = eval("(" + errMsg + ")");
errMsg = errMsg.message;
}
alert("提交" + ajaxInfo.title + "的时候发生错误!\r\n<br>" + errMsg);
if (typeof top.spinStop == "function")
top.spinStop();
if (typeof error == "function") error();
}; //处理success
var success = ajaxInfo.success;
ajaxInfo.success = function(data) {
//显示调试信息
//if (typeof parent.DebugSet != "undefined")
// parent.DebugSet(data.debug); if (typeof success == "function")
success(data); }; //开始执行ajax
$.ajax(ajaxInfo); };
//查询数据
Nature.Ajax.find = function (ajaxInfo) {
ajaxInfo.type = "GET";
var info = ajaxInfo.pagerInfo ;
//处理url,分页和查询
if (typeof info != "undefined") {
if (typeof ajaxInfo.data == "undefined") ajaxInfo.data = {}; if (typeof info.pageSize != "undefined")
ajaxInfo.data["$top"] = info.pageSize; if (typeof info.pageIndex != "undefined")
ajaxInfo.data["$skip"] = (info.pageIndex - 1) * info.pageSize; if (typeof info.orderby != "undefined" && info.orderby != "")
ajaxInfo.data["$orderby"] = info.orderby; } //处理查询条件 //处理返回事件 $orderby
var success = ajaxInfo.success; ajaxInfo.success = function (data) {
//
//判断返回信息
if (typeof data.message != "undefined") {
alert(data.message);
} else {
if (typeof success == "function")
success(data);
}
}; Nature.Ajax(ajaxInfo); };
//添加数据
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); };
基于jQuery的ajax对WebApi和OData的封装的更多相关文章
- jQuery的ajax对WebApi和OData的封装
基于jQuery的ajax对WebApi和OData的封装 WebApi 的使用带来了一个显著的特点,对type有一定的要求.一般ajax的type无非就是两种,GET和POST.如果用JSONP来跨 ...
- 源码来袭!!!基于jquery的ajax分页插件(demo+源码)
前几天打开自己的博客园主页,无意间发现自己的园龄竟然有4年之久了.可是看自己的博客列表却是空空如也,其实之前也有写过,但是一直没发布(然而好像并没有什么卵用).刚开始学习编程时就接触到博客园,且在博客 ...
- Python Django 之 基于JQUERY的AJAX 登录页面
一.基于Jquery的Ajax的实现 1.url 2.vews 3.templates
- 基于JS的ajax的实现,JSON和JSONP,基于JQuery的ajax的实现
基于JS的ajax的实现,JSON和JSONP,基于JQuery的ajax的实现1.基于JS的ajax的实现 step1: var xmlhttp = XMLHttprequest() #实例化一个对 ...
- 份-城市,基于jQuery的AJAX二级联动,用Struts2整合AJAX【非数据库版】
package loaderman.provincecity; import java.io.IOException; import java.util.LinkedHashSet; import j ...
- MVC下通过jquery的ajax调用webapi
如题 jquery的应用,不会的自己去补. 创建一个mvc项目,新建控制器.视图如下: 其中data控制器负责向前台提供数据,home控制器是一个简单的访问页控制器. data控制器代码如下: pub ...
- 基于jQuery的AJAX和JSON的实例
通过jQuery内置的AJAX功能,直接访问后台获得JSON格式的数据,然后通过jQuer把数据绑定到事先设计好的html模板上,直接在页面上显示. 我们先来看一下html模板: ...
- 基于jQuery的ajax系列之用FormData实现页面无刷新上传
接着上一篇ajax系列之用jQuery的ajax方法向服务器发出get和post请求写,这篇主要写如何利用ajax和FormData实现页面无刷新的文件上传效果,主要用到了jQuery的ajax()方 ...
- Asp.Net下,基于Jquery的Ajax二级联动
最近做一个项目,要求实现二级联动效果.背景为:通过学院的选择,联动出专业选项.起初想直接用微软的控件实现Ajax效果,但是DropDownList控件会自动触发PostBack,在后台根本就不好控制, ...
随机推荐
- 锁&锁与指令原子操作的关系 & cas_Queue
锁 锁以及信号量对大部分人来说都是非常熟悉的,特别是常用的mutex.锁有很多种,互斥锁,自旋锁,读写锁,顺序锁,等等,这里就只介绍常见到的, 互斥锁 这个是最常用的,win32:CreateMute ...
- Surface Normal Vector in OpenCascade
Surface Normal Vector in OpenCascade eryar@163.com 摘要Abstract:表面上某一点的法向量(Normal Vector)指的是在该点处与表面垂直的 ...
- poj 2226 Muddy Fields(合理建图+二分匹配)
/* 题意:用木板盖住泥泞的地方,不能盖住草.木板任意长!可以重叠覆盖! '*'表示泥泞的地方,'.'表示草! 思路: 首先让我们回忆一下HDU 2119 Matrix这一道题,一个矩阵中只有0, 1 ...
- 用ticons指令结合ImageMagickDisplay工具批量生成Android适应图片
用ticons指令结合ImageMagickDisplay工具批量生成Android适应图片 ticons的用法可以百度 这里记录下具体的编译方法 在安装了ticons和ImageMagickDisp ...
- [Linux] LD_LIBRARY_PATH
该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径(该路径在默认路径之前查找).若共享库不在缺省路径/lib或者/usr/lib下,就需要指定其他路径.实践中的一种解决方案是, ...
- SQL Server代理(3/12):代理警报和操作员
SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. 如我们在这个系列的文章里所见,SQL Se ...
- C#密封类
密封类 密封类使用sealed修饰符声明. 密封类中不可能有抽象方法[因为:抽象方法必须在抽象类中,而抽象类不能是密封的或者是静态的,也就是说abstract 和sealed不能同时修饰一个类] ...
- HTML5使用Div标签来实现表格
当支持HTML5时,我们可以使用样式把DIV实现一个表格table. 关键样式语法:display: table,display: table-row,display: table-cell 下面例子 ...
- PHP表单数据写入MySQL代码
<h1>插入操作</h1> <?php if(!isset($_POST['submit'])){ //如果没有表单提交,显示一个表单 ?> <form ac ...
- C# ~ 泛型委托
泛型 应用 1. 比较 2 个对象的大小? 参考 1. .NET面试题系列 - 对象大小比较:由一个泛型方法想到的 - 对象大小比较: