各种AJAX方法的使用比较

原文http://www.cnblogs.com/fish-li/archive/2013/01/13/2858599.html

阅读目录

AJAX技术经过这么多年的发展,出现了一些框架或类库用于简化开发工作,不同的框架类库的使用方法也各不相同。 现在,再回头看看这些技术,看看这些框架类库,我们能感受到技术在不断地发展,AJAX开发越来越容易了。

本文收集了在ASP.NET平台上,一些具体代表性的AJAX开发方法,我将用实际的示例代码来演示如何使用它们, 让您感受AJAX的进化历程,同时也希望将一些优秀的AJAX开发方法介绍给您。

为了方便地介绍这些AJAX开发方法,我将它们划分为四代技术。
注意:按代划分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客户端类库外,还在客户端为WebService1生成了代理脚本。

有了这些代码后,我们可以用下面的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};
    WebService1.AddCustomer(customer, ShowResult);
}

基本上还是与服务端的编码方式差不多,先创建一个customer对象,再传给调用方法。

在那个年代之前(2006年),原始的AJAX实现方式非常复杂,而这种方法让客户端代码风格看起来与服务端十分类似,这确实是个了不起的设计思路。 然而各种技术一直在改进中,现在,2013年,当我们再来回顾这种方法时,会发现它确实存在一些不完善的地方, 以至于现在使用这种方法的人很少了,这种技术被淘汰了!

其实我们可以从另一外角度来思考:如果这种方法真的很优秀,它就不可能被淘汰,正是因为有更优秀的方法出现了,它才会遭到淘汰的命运。

回到顶部

新技术的改进方向

前面介绍的那种AJAX方法能让客户端的调用代码与服务端的代码风格基本一致,看似很完美的方法为什么会被淘汰了呢?

我来分析一下这种开发方法的缺陷:
1. 前端代码不够独立,必须要在页面中添加引用之后才能调用服务端,这其实是一种强耦合。
2. 出现了更优秀的前端框架能简少获取调用参数的代码量。

继续阅读本文,您会发现后面我将要介绍的新方法都朝着解决这些缺陷在努力,
这些缺陷也算是指出了新技术的改进方向。

由于前端在调用服务端时,需要事先生成代理脚本,这种设计会阻碍前端代码的封装性。
您可以想象一下:如果客户端需要一个【获取当前用户信息】的功能,而这个功能必须由服务端实现的,
此时,我们就只能指望服务端为客户端生成代理类来调用这个功能了。
但这个功能太有用,许多地方都需要使用,您是不是会想将它提取到一个公用的文件中?

遗憾的是:就算您将这段调用代码提取到一个公共的public.js文件中,每个页面在引用public.js后,
并不能调用【获取当前用户信息】功能,因为代理脚本并不一定存在,public.js中的代码还不能运行起来。
怎么办?

答:为每个引用public.js的页面,再添加ScriptManager引用那个服务吧。

共用性越高的功能,您会发现这种引用代码的重复度也就越高。
简单说来,这种方法将WebService, aspx页面, js代码耦合在一起了。
由于耦合,您越用越发现越麻烦。

这种生成代理脚本的开发方法虽然能让前端代码与后端代码的风格一致,然而,
前端与后端毕竟不是同一种开发语言,它们要关注的方向也是不一样的。尤其是当更优秀的前端框架出现后,
这种后端包办前端的方法不仅让后端与前端耦合在一起,而且还限制了前端技术的发展,
最终只能是被抛弃的命运!

现在请记住我们为了提交一个Customer信息写了什么样的代码:

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};

我在介绍第四代技术时,您会发现它们消失了!

回到顶部

第二代技术:jQuery直接调用WebService

随意jQuery前端类库的流行,另一种新的开发方法也开始流行起来了。

HTTP调用本来是个很简单很透明的技术,只要指定一个URL,构造一个请求体就可以了, 前端代理脚本的方法将这个过程封装了起来,由于它的封装制造了耦合并限制前端的发展。 新的AJAX技术只能突破这个限制,舍弃这些代理脚本,直接调用后端代码。

下面的示例代码还是基于前面的示例,唯独不同的是:不是需要代理类,现在是直接调用服务端。

由于后端的服务代码没有改变,我也就不再贴出它们了,而且页面也不需要再添加什么引用,我们就直接看前端代码好了:

$.ajax({
    type:"POST", url: "/WebService1.asmx/Add",
    contentType:"application/json",
    data:"{a: 1, b: 2}",
    dataType:'json',
    success:function(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 jsonStirng = $.toJSON( {customer:  customer} );

$.ajax({
    type:"POST", url: "/WebService1.asmx/AddCustomer",
    contentType:"application/json",
    data: jsonStirng,
    dataType:'json',
    success:function(result){
        $("#output").val(result.d);
    }
});

主要的代码还是一样的,集中在获取调用参数,但是要转成JSON格式。

再次一次提醒:不要老是盯着要指定一大堆的jQuery参数,它们可以通过设置默认值的方式解决。
我之所以现在不想让它们消失,是因为后面还有更好的方法,先留着它们吧。

说明:这种方法不仅可以用于调用WebService,也可以调用WCF (basicHttpBinding),毕竟它们都使用HTTP协议。
不过,WCF还有一堆烦人的配置要设置,但这不是jQuery的问题,这是服务端框架的缺陷。

回到顶部

第三代技术:更简单的数据格式

前面我们看到了可以利用jQuery调用WebService,不过JSON的转换过程感觉有些多余,浏览器的提交就没有这个转换步骤嘛。
有时看到一些家伙们着还在JavaScript中拼接JSON字符串,我非常反感,所以这次的示例代码并没有给那种方法抹黑,我采用了一个JSON插件。

第三代技术就完美地解决了输入输出必须采用JSON问题,而且解决了POST的限制。

由于这次变革改变了数据格式,所以服务端也发生了改变,
新的框架解决了这些问题,例如:ASP.NET MVC框架,MyMVC框架都支持这个开发方式。

来看一下现在服务端的代码:

[Action]
public int Add(int a, int b)
{
    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=vlaue的格式,与浏览器的方式一致。 由于没有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>

前面用了三种方法在提交这个表单,下面我们再来看一下更简单的提交方式:

<script type="text/javascript">
$(function(){

    // 只需要下面这个调用就可以将表单改成异步提交方式!
    $("#form1").ajaxForm({
        success:function(result){
            $("#output").val(result);
        }
    });
});

</script>

为了更清楚展示这种方法,我甚至把script标签也贴出来了。
如果您用过jQuery就应该能发现,真正的代码就只有ajaxForm的那个调用。
说明:ajaxForm是jQuery.form插件提供的功能。

服务端的代码继续使用前面示例的代码,所以就不贴出了。

再对比前面几种AJAX的实现方法,您说哪种方法最简单?

您对第四代AJAX技术有兴趣吗?
我还为它设计了三种不同场景下的示例,让您感受它的强大与简单,请继续阅读。

回到顶部

多submit按钮的提交(用jQuery.form实现)

您认为前面的示例太简单了,是吗?
可能有人会说,如果有多个submit按钮,这种方法就不合适了,我要响应每个按钮,为它们指定不同的URL !

真是这样吗? 看下面的示例吧。

相关的前端代码如下:

<form id="form1" action="/AjaxTestAutoAction/submit.cspx" method="post">
    <p><span>Input:</span>
        <input type="text" name="input" style="width: 300px" value="Fish Li" /></p>
    <p><span>Output:</span>
        <input type="text" id="output" style="width: 300px" readonly="readonly" /></p>
    <input type="submit" name="Base64" value="转换成Base64编码" />&nbsp;&nbsp;
    <input type="submit" name="Md5" value="计算md5" />&nbsp;&nbsp;
    <input type="submit" name="Sha1" value="计算sha1" />
</form>

<script type="text/javascript">
$(function(){
    $("#form1").ajaxForm(function(result) {
        $("#output").val(result);
    });
});
</script>

服务端代码:

public class AjaxTestAutoAction
{
    [Action]
    public string Base64(string input)
    {
        return Convert.ToBase64String(Encoding.Default.GetBytes(input));
    }

    [Action]
    public string Md5(string input)
    {
        byte[] bb = Encoding.Default.GetBytes(input);
        byte[] md5 = (new MD5CryptoServiceProvider()).ComputeHash(bb);
        return BitConverter.ToString(md5).Replace("-", string.Empty);
    }

    [Action]
    public string Sha1(string input)
    {
        byte[] bb = Encoding.Default.GetBytes(input);
        byte[] sha1 = (new SHA1CryptoServiceProvider()).ComputeHash(bb);
        return BitConverter.ToString(sha1).Replace("-", string.Empty);
    }
}

代码仍然很清晰:
1. 服务端定义三个方法,对应三个submit按钮。
2. 前端还是只调用一个ajaxForm解决所有问题。

这种方法就是由前端的 jQuery, jQuery.form 以及服务端的MyMVC框架
共同实现的。
想像一下利用其它三种方法需要多少代码吧。

回到顶部

批量输入控件的提交(用jQuery.form实现)

再来展示另一个现实的例子,批量输入界面的提交。

页面表单代码如下:

JavaScript代码:

<script type="text/javascript">
$(function(){

    $("#form1").ajaxForm({
        success:function(result){
            $("#output").val(result);
        }
    });

});

服务端代码如下:

这个示例的全部代码就这么多,废话不想多说,您自己去想用其它方法需要多少代码!

回到顶部

提交复杂表单(用jQuery.form实现)

前面的示例都是直接提交表单,没有验证表单的过程,而且都以Textbox控件为主,再来个复杂的表单示例。

页面表单代码如下:

JavaScript代码:

<script type="text/javascript">
$(function(){

    $("#form1").ajaxForm({
        beforeSubmit: ValidateForm,
        success:function(result){
            $("#output").val(result);
        }
    });

    function ValidateForm(formData, jqForm, options) {
        if( jqForm.context.ProductName.value.length == 0 ){
            alert("商品名称不能为空。");
            $(jqForm.context.ProductName).focus();
            return false;
        }
        return true;
    }
});

</script>

服务端代码:

[Action]
public string AddProduct(Product product)
{
    // 简单地返回一个XML字符串。
    // 告诉客户端:服务端收到了什么样的数据。
    return XmlHelper.XmlSerialize(product, Encoding.UTF8);
}

回到顶部

各种AJAX开发方法的对比与总结

看过了这些示例后,我们再来回顾这些AJAX方法的进化过程:

1. 以ASP.NET AJAX为代表的【生成客户端代理脚本调用服务端】技术, 为了包装原始AJAX的复杂过程,服务端为客户端生成了代理脚本, 这种封装后的客户端在调用方式上与服务端基本一致,看起来简化了不少,而且降低了开发门槛, 然而,它的优点也是它是它的最大缺点:服务端包办了客户端的事情,它完全没有想到客户端技术也在进步! 当更优秀的前端技术出现时,它的结局只能是淘汰。

2. 【jQuery直接调用WebService】可以看做是第一代技术的改进,它丢弃了服务端生成代理脚本的功能, 直接在客户端准备服务端所需要的数据格式,借助jQuery内部对XmlHttpRequest的封装,也能方便地调用服务端。 这种方法解决了客户端、服务、页面三方的耦合,但是数据格式却受到序列化方式的限制,使得起来怪怪的。 这种怪怪的感觉其实也是不方便的表现。

3. 为了让前端更方便地调用服务端,服务端框架只能改变,ASP.NET MVC框架和MyMVC框架都支持更简单的数据格式, 而且不需要那个多余的asmx文件,直接用类库就可以响应客户端请求。 这类技术的最主要特点是:用更简单的数据格式就可以调用服务端。 由于数据格式简单化,为以后的继续改进留下了机会。

4. 由于服务端不要求序列化的数据格式,且前端技术仍在进步,终于jQuery.form插件可以让我们不需要关注表单数据的收集过程, 它能模拟浏览器的提交行为,正确识别【成功控件】并将它们提交到服务端,因此代码得到最大限度的缩减,让AJAX开发过程更加容易。

前面几个采用jQuery.form的示例也让我们看到:不管表单是什么样的,永远只需要一个调用。
而且它将jQuery的调用过程也做了非常好的封装,所以我认为这是最容易使用的AJAX开发方法。

回到顶部

相关链接

1. jQuery: http://jquery.com/

2. jQuery.form: http://jquery.malsup.com/form/

3. MyMVC: http://www.cnblogs.com/fish-li/archive/2012/02/12/2348395.html

回到顶部

招聘信息

公司需要若干名 .net 方面的高级开发人员,要求熟悉以下技术领域:
1. .net framework
2. ASP.NET
3. SQL SERVER (T-SQL, SP)
4. JavaScript, jQuery
5. CSS
6. 常见的设计模式。

说明:
1. 公司名称:明源软件
2. 工作地点:武汉。
3. 我只是负责【推荐】,具体细节请发邮件给我:liqifeng0503@163.com
4. 咨询招聘相关的疑问也请发邮件给我,评论中的疑问一律不回复!

点击此处下载示例代码

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。
如果,您希望更容易地发现我的新博客,不妨点击一下右下角的【关注 Fish Li】。
因为,我的写作热情也离不开您的肯定支持。

感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是Fish Li 。

时间: 2024-10-27 04:26:27

各种AJAX方法的使用比较的相关文章

jquery.Ajax()方法调用Asp.Net后台的方法解析

 本篇文章主要是对jquery.Ajax()方法调用Asp.Net后台的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助 利用JQuery的$.ajax()可以很方便的调用asp.net的后台方法. 先来个简单的实例热热身吧.   1.无参数的方法调用 asp.net code:    代码如下: using System.Web.Script.Services;      [WebMethod]    public static string SayHello()    {   

jQuery ajax:将类AJAX方法包装起来

上一篇文章,将jQuery.ajax中的一些细节补充完.这篇文章讲解如果将类AJAX方法都包装进jQuery.ajax 中.下篇文章则讲解各预过滤器和分发器的细节. 为什么要包装起来? 我们知道,古老的 XMLHttpRequest出于同源策略考虑,是不支持跨域的.所以,在前端想动态加载跨域Javascript脚本,通常是 使用被称为Script DOM Element的方案,如: var scriptElem = document.createElement ("script");

JQuery中$.ajax()方法参数详解及应用

 JQuery中$.ajax()方法想必大家并不陌生吧,在本文将为大家介绍下其参数及应用示例,感兴趣的朋友不要错过 url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址.    type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和    delete也可以使用,但仅部分浏览器支持.    timeout: 要求为Number类型的参数,设置请求超时时间(毫秒).此设置将覆盖$.ajaxSetup()方法的

JS使用ajax方法获取指定url的head信息中指定字段值的方法

 这篇文章主要介绍了JS使用ajax方法获取指定url的head信息中指定字段值的方法,实例分析了Ajax操作URL中head信息的技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了JS使用ajax方法获取指定url的head信息中指定字段值的方法.分享给大家供大家参考.具体分析如下: 下面的JS代码用来获取ajax_info.txt的head信息中的Last modified属性,最后修改时间 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1

jquery中get,post和ajax方法的使用小结

 本篇文章主要是对jquery中get,post和ajax方法的使用进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 在JQuery中可以使用get,post和ajax方法给服务器端传递数据   get方法的使用(customForGet.js文件):   function verify(){ //1.获取文本框的数据   //通过DOM的方式获取 //document.getElementByIdx("userName"); //通过JQuery的方式获取 var jq

Jquery中ajax方法data参数的用法小结

 本篇文章主要是对Jquery中ajax方法data参数的用法进行了总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助  代码如下: $.ajax({    type: "POST",    url: "some.php",    data: "name=John&location=Boston", //第一种方式传参   // data: {name:"John",location:"Boston&qu

JQUERY中的ajax方法怎样通过JSONP进行远程调用

 这一节主要演示下在JQUERY中的ajax方法怎样通过JSONP进行远程调用,需要的朋友可以参考下 关于JSONP的概念和为什么要使用JSONP网上已经有很多教程,这一节主要演示下在JQUERY中的ajax方法怎样通过JSONP进行远程调用    首先介绍下$.ajax的参数  type:请求方式 GET/POST  url:请求地址  async:布尔类型,默认为true 表示请求是否为异步,如果为false表示为同步.  dataType:返回的数据类型  jsonp:传递给请求处理程序或

yii ajax-yii框架里怎么实现Jquery Ajax方法传值到控制器action方法里

问题描述 yii框架里怎么实现Jquery Ajax方法传值到控制器action方法里 $.ajax({ type:'post', url:"/www/index.php?r=home/CkUser",//地址写什么才是对的 data:{"name":val}, success:function(msg){ alert("正确"); $("#nameinfo").html(msg); }, 解决方案 地址直接写根下的控制器下的

各种AJAX方法的使用比较详解_AJAX相关

阅读目录 开始 第一代技术:生成客户端代理脚本调用服务端 新技术的改进方向 第二代技术:jQuery直接调用WebService 第三代技术:更简单的数据格式 第四代技术:直接提交表单 多submit按钮的提交(用jQuery.form实现) 批量输入控件的提交(用jQuery.form实现) 提交复杂表单(用jQuery.form实现) 各种AJAX开发方法的对比与总结 相关链接 本文收集了在ASP.NET平台上,一些具体代表性的AJAX开发方法,我将用实际的示例代码来演示如何使用它们,让您感

Jquery基于Ajax方法自定义无刷新提交表单Form实例_AJAX相关

本文实例讲述了Jquery基于Ajax方法自定义无刷新提交表单Form的方法.分享给大家供大家参考.具体实现方法如下: Jquery的$.ajax方法可以实现ajax调用,要设置url,post,参数等. 如果要提交现有Form需要写很多代码,何不直接将Form的提交直接转移到ajax中呢. 以前的处理方法: 如Form代码如下: 复制代码 代码如下: <form id="Form1" action="action.aspx" method="pos