基于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,在后台根本就不好控制, ...
随机推荐
- struts之动态方法调用使用通配符
一.DMI动态方法调用的其中一种改变form表单中action属性的方式已经讲过了.还有两种,一种是改变struts.xml配置文件中action标签中的method属性,来指定执行不同的方法处理不同 ...
- 【WP 8.1开发】电子罗盘
罗盘,估计也不用我过多介绍,学过初中物理的都知道,不管是指南针,还是指北针,其本质就是用来辨别方向的. 操作电子罗盘伟感器也不复杂,主要就是两个角度: 1.当前方向与磁北的夹角: 2.当前方向与地北的 ...
- WPF自定义控件与样式(10)-进度控件ProcessBar自定义样
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Pro ...
- javascript运算符——位运算符
× 目录 [1]二进制 [2]非 [3]与[4]或[5]异或[6]左移[7]右移[8]>>>[9]应用 前面的话 位运算符是非常底层的运算,由于其很不直观,所以并不常用.但是,其速度 ...
- hdu3635 Dragon Balls(带权并查集)
/* 题意:有N个城市, 每一个城市都有一个龙珠(编号与城市的编号相同),有两个操作 T A ,B 将标号为A龙珠所在城市的所有的龙珠移动到B龙珠所在城市中! 思路:并查集 (压缩路径的时候将龙珠移动 ...
- 【踩坑经历】一次Asp.NET小网站部署踩坑和解决经历
2013年给1个大学的小客户部署过一个小型的Asp.NET网站,非常小,用的sqlite数据库,今年人家说要换台服务器,要重新部署一下,好吧,虽然早就过了服务时间,但无奈谁叫人家是客户了,二话不说,上 ...
- Linux的学习--配置LNMP环境
最近,回到公司,发现电脑都换成linux系统了...很无力... 配置环境,跑起项目来就花了一天...额...在这里记录一下-- 系统是ubuntu 12.04. 一.安装nginx1:ubuntu因 ...
- PetaPoco 访问SQL SERVER 存储过程
博客园有篇文章<小巧方便的ORM类库——PetaPoco> 介绍了PetaPoco调用存储过程: //调用存储过程 db.Execute("exec procSomeHandl ...
- 精选12个时尚的 CSS3 效果【附源码下载】
这里是精选的12个很炫的 CSS3 效果.CSS3 是对 CSS 规范的一个很大的改善和增强,它使得 Web 开发人员可以很容易的在网站中加入时尚的效果.以前很多需要编写复杂的 JavaScript ...
- Windows Azure Virtual Network (6) 设置Azure Virtual Machine固定公网IP (Virtual IP Address, VIP) (1)
<Windows Azure Platform 系列文章目录> 注意:本文介绍的是Global Azure (http://www.windowsazure.com),如果你使用的是由世纪 ...