AJAX技術經過這麼多年的發展,出現了一些框架或類別庫用於簡化開發工作,不同的框架類別庫的使用方法也各不相同。現在,再回頭看看這些技術,看看這些框架類別庫,我們能感受到技術不斷發展,AJAX開發越來越容易了。
閱讀目錄
開始
第一代技術:產生客戶端代理程式腳本調用服務端
新技術的改進方向
#第二個技術:jQuery直接呼叫WebService
第三代技術:更簡單的資料格式
#第四代技術:直接提交表單
#多submit按鈕的提交(以jQuery.form實作)
#批次輸入控制項的提交(以jQuery.form實作)
提交複雜表單(用jQuery.form實作)
#各種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编码" /> <input type="submit" name="Md5" value="计算md5" /> <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開發方法。
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
django使用ajax post資料出現403錯誤如何解決
##
以上是各種AJAX方法的使用比較詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!