时间真快,转眼一个月快结束了,一个月没写博客了!手开始生了,怎么开始呢……
示例下载:使用jQuery.form插件,实现完美的表单异步提交.rar
抓住6月份的尾巴,今天的主题是
今天我想介绍的是一款jQuery的插件:Jquery.form.js 官网。
通过该插件,我们可以非常简单的实现表单的异步提交,并实现文件上传、进度条显示等等。
现在我们从一个ASP.NET同步表单提交开始,然后再将其转化为异步的表单提交。我写了3种表单提交示例,并简单分析了各种方式的利弊。
当然主题还是使用jQuery表单插件轻松实现表单异步提交以及分析下该插件的源码。
ASP.NET服务器端控件实现同步表单提交
ASP.NET服务器控件最大特征就是标签包含ID和runat=”server”属性,在客服端页面内容中会输出类似<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGR/8ZxOm5Tn0sfHNJaqE12hKqqJTQ==">标签,用于存储控件值数据。如下:
<form runat="server" id="server_form" method=”post”> <table border="1"> <tr> <td>用户名:</td> <td> <asp:TextBox ID="txtLoginName" runat="server" AutoPostBack=”true” ></asp:TextBox> </td> </tr> <tr> <td colspan="2" style="text-align: center"> <asp:Button ID="btnSubmit" runat="server" Text="服务器控件同步提交模式" /> <asp:Button ID="btnUnSubmit" runat="server" OnClientClick="return false;" Text="不提交表单" /> </td> </tr> </table> </form> <asp:Label ID="labResponse" runat="server"></asp:Label>
我们用ASP.NET服务器控件构建了一个表单,在ASP.NET页面中有这样限定:
1) 一页只能有一个服务器端 Form 标记,其他服务器端控件都在该表单中。
2) 页面中服务器端Form中任何导致页面回发的服务器端控件事件都会触发表单提交事件submit。比如:
a) 单击没有在OnClientClick事件中return false的服务器端按钮控件
b) 将AutoPostBack属性设置为true的TextBox、RadioButton、CheckBox、DropDownList等服务器端控件的值改动时都会触发页面回发。
c) 另外:type=”submit”的客服端标签<input type=”submit” />导致表单提交
此方案优势:
1) 我们在后台可以非常轻易的获取服务器端控件的值,比如使用this. txtLoginName.Text访问控件的值或根据表单提交方式在this.Context.Request中获取表单元素值。
2) 我们在后台可以轻松设置页面服务器端控件的值,比如使用this. labResponse.Text = “表单提交成功”。
此方案劣势:
劣势很明显,效率低下,每一次导致的页面回发都会触发完整的ASP.NET页面生命周期,造成出现“白页”的情况。(更多描述请看:ASP.NET编程模型之ASP.NET页面生命周期图解)
jQuery异步提交表单
现在我们已经意识到使用同步方式提交表单会造成出现“白页”的糟糕用户体验,那好,现在我使用上一篇分享的技术《触碰jQuery:AJAX异步详解》来将上面同步提交表单调整为异步提交表单的方式。
<form id="form1" method="post"> <table border="1"> <tr> <td>用户名:</td> <td> <input type="text" name="loginName" /></td> </tr> <tr> <td>爱 好:</td> <td> <input type="checkbox" name="cbLoveYy" value="1" />游泳 <input type="checkbox" name="cbLoveYx" value="1" />游戏 <input type="checkbox" name="cbLovePs" value="1" />爬山 </td> </tr> <tr> <td colspan="2" style="text-align: center"> <input id="btnAjaxSubmit" type="submit" value="jQuery.ajax提交" /> </td> </tr> </table> </form>
jQuery提交代码如下:
<script type="text/javascript"> $(document).ready(function () { $("#btnAjaxSubmit").click(function () { var options = { url: 'async_submit_test1.aspx?action=SaveUserInfo', type: 'post', dataType: 'text', data: $("#form1").serialize(), success: function (data) { if (data.length > 0) $("#responseText").text(data); } }; $.ajax(options); return false; }); }); </script>
我们通过$("#form1").serialize()将表单元素的数据转化为字符串,然后通过$.ajax()执行异步请求资源。
方案:jQuery.ajax() + .aspx请求
此方案优势:
1) 我们不会感觉页面的“闪一闪”效果
2) 我们不会因为服务器耗时响应而导致出现“百页”的糟糕用户体验。
此方案劣势:
1) 此方案中我还是使用了aspx页面去响应请求,只是在后台通过action参数去做相应处理,尽管是异步操作但却完完整整的跑了一遍ASP.NET页面生命周期(这也是在Response.Write()输出完自己的东西后必须调用Response.End();来提前终止生命周期,否则页面信息也会一起返回)
2) jQuery库提供的序列化表单字符串方法不能收集文件上传的表单元素,如,$("#form1").serialize()。所以对于包含文件上传的表单我们还需通过<iframe>模拟异步表单提交。(<iframe>模拟异步表单提交的过程我将在分析jQuery.form插件的源码小节进行说明)
(jQuery