(本文借鉴了FishLi的ajax的方法比较)
复习下ajax的生成历史:
第一代技术:生成客户端代理脚本调用服务端
这技术展示了一代的ajax框架的主要设计思想:在服务端为客户端生成代理脚本,然后由这些代理脚本调用服务端,调用者可以不必知道整个过程如何实现的,而且在客户端的调用风格也基本与服务端的代码类似。
这类代表有:asp.net ajax ajaxpro 二个服务端框架。
下面将asp.net ajax 框架演示下如何进行ajax开发:
首先创建个webservice服务:
[ webService(Namespace="http://tempuri.org/")]
[ webServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]
//若要允许使用asp.net ajax 从脚本中调用此web服务,请取消对下行的注释。
[System.Web.Script.Services.ScriptService] public class WebService1 : System.Web.Services.WebService {
[WebMethod]
public int Add(int a,int b){
return a+b;
}
这代码就是一个普通webservice代码,注意:在类的定义上加了一个ScriptService 修饰特性
接下来,我们还需要一个aspx页面,用ScriptManager为它生产成客户端的代理脚本:
<asp:ScriptManager ID ="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="/WebService1.asmx" InlineScript="true"/>
</Services>
</asp:ScriptManager>
说明:InlineScript="true"的设置并不是必须的,只是为了让我们看到ScriptManager到底生成什么代码
从截图可以看出,除了引入了二个必要的ajax客户端类库外,还在哭护短为webservice
有了这些代码后,我们可以用下面的javaScript 代码调用服务端;
function Call_Add(){
WebService1.Add(1,2,ShowResult);
}
function ShowResult(result){
document.getElementById("output").value=result;
}
再来个参数复杂示例,从服务端开始,先定义一个参数类型:
public class Customer{
public string Name{ get;set;}
public int Age{get;set;}
public string Address{get;set;}
public string Tel{ get;set;}
public string Email{get;set;}
}
webserice的代码:
[webmethod]
public string AddCustomer(Customer customer)
{
if(customer==null)
return "customer is null.";
//简答返回一个xml字符串
//告诉客户端:服务端收到了什么样的数据
return XmlHelper.XmlSerialize(customer,Encoding.UTF8);
}
仍然借用前面的ScriptManager设置,来看JavaScript的调用代码:
function Call_AddCustomer(){
var customer={Name:document.getElementById("txtName").value,
Age:document.getElementById("txtAge").value,
Address:document.getElementById("txtAddress").value,
Tel:document.getElementById("txtTel").value,
Email:document.getElementById("txtEmail").value};
WebService.AddCustomer(customer,ShowResult);
}
基本上还是与服务端的编码方式差不多,先创建一个customer对象,再传给调用方法。
---------------------------------------- - - -- - - -- 新技术的改进 - - - - -- - --------------------------
分析下上面代码开发的缺陷:前端代码不够独立,必须在页面中添加引用后才能调用服务端,强耦合。
出现了更优秀的前端框架能减少获取调用参数的代码量
由于前端在调用服务端时,需要事先生成代理脚本,这种设计会阻碍前端代码的封装性。 您可以想象一下:如果客户端需要一个【获取当前用户信息】的功能,而这个功能必须由服务端实现的, 此时,我们就只能指望服务端为客户端生成代理类来调用这个功能了。 但这个功能太有用,许多地方都需要使用,您是不是会想将它提取到一个公用的文件中??????
悲剧的是:就算把这段代码提取到一个公用的public.js文件中,每个页面的引用public.js 后,并不能调用【获取当前用户信息】功能,因为代理脚本并不一定存在,public.js中的代码还不能运行起来
为每个引用public.js的页面,添加ScriptManager 引用那个服务吧。
公用性越高,引用代码重复性越高,简单的说这种方法将webservice,aspx页面,js代码耦合在一起了
由于耦合所以越来越麻烦
-----------------------------------------------------------------------------
第二代技术:JQuery直接调用webService
随意的jQuery前端类库的流行,另一种新的开发方法也开始流行起来
http调用本来是个很简单很透明的技术,只要制定一个url,构造一个请求体就可以了,前端代理脚本的方法将这个过程封装了起来,由于它的封装制造了耦合并限制前端的发展,新的Ajax技术只能突破这个限制,舍弃这些代理脚本,直接调用后端代码。
下面示例:不需要代理类,直接调用服务器
$.ajax({
type:"POST",url:"/WebService1.asmx/Add",
contentType:"application/json",
dataType:'json',
success:fuction(result){
$("#output").val(result.d);
}
});
这段代码也能调用服务端的Add方法
由于服务端采用json数据格式,所以需要在客户端多指定一些请求头,这些事情以前是由代理脚本完成的,虽然现在代码稍微多点,但是耦合没了,便于提取公用代码。如果一直用这种方式调用webservice,那么jquery提供了设置默认参数的功能,我们可以利用这个特性减少代码量。还是再来看下前面那个复杂的参数类型的前端调用代码吧:
var customer={Name:$("#txtName").val(),
Age:$("#txtAge").val(),
Address:$("#txtAddress").val(),
Tel:$("#txtTel").val(),
Email:$("#txtEmail").val()};
var jsonString=$.toJSON({customer:customer});
$.ajax({
type:"POST",url:"/WebServicel.asmx/AddCustomer",
contentType:"application/json",
data:jsonString,
dataType:'json',
success:function(result){
$("#output").val(result.d);
}
});
主要代码还是一样的,集中在获取调用参数,但是要转换json格式
不要盯着指定一大堆的jQuery参数,他们可以通过设置默认值的方式解决
这方法不仅可以用于调用webservice,也可以调用WCF(basicHTtpBinding)毕竟他们都是用http协议,不过wcf,还有一堆烦人的配置要设置,但这不是jquery的问题,这时服务端框架的缺陷
-----------------------------------------------------三代技术:更简单的数据格式
之前看到的利用jquery调用webservice 不过json的转换过程感觉有些多余,浏览器的提交就没有这个转换步骤。
第三代技术完美的解决了输入输出必须采用的json问题,而且解决了post限制
由于这次变革改变了数据格式,所以服务端也发生了改变,新的框架解决了这些问题:asp.net mvc 框架,mymvc框架都支持这个开发方式
【Action】
public int Add(int a,intb)
{
return a+b;
}
[Action]
public String AddCustomer(Customer customer)
{//简单地返回一个xml字符串
//告诉客户端:服务端收到了什么样的数据
return XmlHelper.XmlSerialize(customer,Encoding.UTF8);
}
注意:这种ajax技术没有雨客户端的任何耦合,只要知道一个url就可以调用了,来看客户端的代码吧;
$.ajax({
type:"POST",url:"/AjaxDemo/Add.cspx",
data:{ a:1,b:2},
success:function(result){
$("#output").val(result);
}
});
//第二个调用
var customer={Name:$("#txtName").Val(),
Age:$("#txtAge").val(),
Address:$("#txtAddress").val(),
Tel:$("#txtTel").val(),
Email:$("#txtEmail").val()
};
$.ajax({type:"POST",url:"/AjaxDemo/AddCustomer.cspx",
data:customer,
success:function(result){
$("#output").val(result);
}
});
注意:type:"POST"并不是必须的,您也可以把他们改成get请求
如果此时用fiddler查看请求会发现请求的数据采用的是key--value& key--value的格式,与浏览器的范式一致,由于没有json数据格式的限制,现在参数项简单了
---------------------直接提交表单-----------------------
<form id="form1" action="/AjaxDemo/AddCustomer.cspx" method="post">
<p><b>新增客户资料</b></p>
<span>Name: </span><input type="text" name="Name" value="abc" /><br />
<span>Age: </span><input type="text" name="Age" value="20" /><br />
<span>Address: </span><input type="text" name="Address" value="武汉" /><br />
<span>Tel:</span> <input type="text" name="Tel" value="12345678" /><br />
<span>Email: </span><input type="text" name="Email" value="test@163.com" /><br />
<br />
<input type="submit" name="btnAddCustomer" value="保存客户资料" />
</form>
之前用了3中方式提交他,下面用个简单的提交方式:
<script type="text/javascript">
$( function()){
//只需要下面的这个调用就可以把表单改成异步提交方式!
$("#form1").ajaxForm({
success:function(result){
$("#output").val(result);
}
});
});
</script>
为了更清楚展示这种方法,我甚至把script标签页贴出来了。
如果您用过jQuery就可以发现,真正的代码就只有ajaxForm的那个调用。
说明:ajaxform是jQuery.form插件提供的功能
服务端的代码继续使用前面示例的代码,所以就不贴出了。
在对比前面代码继续使用前面示例的代码,所以就不贴出了
-