网页的基本职能有两个方面:信息显示和信息收集。所有的页面元素都是围绕这两个基本职能构建的,如div、table、input、img等。
所有的网页元素都可以实现信息显示的职能,但是信息收集,在传统表单提交方式下,只能由“表单系列”元素实现,如input(text,file,button,hidden,checkbox,radio)、select、img等。
界定表单元素的一个方法是判断此元素是否具有两个属性:name和value。
下面我们以一个用户登录表单为例来讲解表单提交的要点,代码如下:
<html> <head> <title>用户登录</title> </head> <body> <!-- form表单元素, 作为一个可提交到服务端的信息区域块 method: 提交的方式, get和post action: 提交的服务端地址 --> <form method="get" action="login.aspx"> 账号:<input name="id" type="text" style="width:130px;" /><br /> 密码:<input name="pwd" type="password" style="width:130px;" /><br /> <div style="padding-left:90px;padding-top:5px;"> <input name="mem" type="checkbox" value="1" />记住我? </div> <div style="padding-left:90px;padding-top:5px;"> <input type="reset" value="重置"/> <input type="submit" value="登录"/> </div> </form> </body> </html>
当输入内容提交后,如果是get方式,会在浏览器网址显示如下内容:
http://.../login.aspx?id=edojs.com&pwd=123456&mem=1
可以看到有id、pwd和mem三个参数,以及他们的值。
此时,页面的数据提交工作已经完成,需要服务端做数据接收的处理了,代码如下:
String id = Request["id"]; String pwd = Request["pwd"]; String mem = Request["mem"]; //...对收到的数据做处理,进行一些数据库的操作
无论服务端是ASP、PHP、JSP或ASP.NET,都基于这种HTML表单提交的方式进行数据交互。
注:如果您不是ASP.NET开发者,到此可以跳过本节,直接看Ajax无刷新交互;如果您是ASP.NET开发者,可能会对以上内容存在疑虑,请继续阅读。
在ASP.NET平台下,情况有一些改变了。微软实现了一个WebForm的概念,虽然本质还是以上的方式,但是可以将Web编程概念向Windows编程靠拢。
使用ASP.NET开发的程序员,会非常熟悉一个叫做“服务端控件”的东西,下面用ASP.NET的服务端控件实现以上的登录页:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="kb_Default" %> <html> <head runat="server"> <title>用户登录</title> </head> <body> <form id="form1" runat="server"> 账号:<asp:TextBox ID="id" runat="server"></asp:TextBox><br /> 密码:<asp:TextBox ID="pwd" runat="server" TextMode="Password"></asp:TextBox><br /> <asp:Button ID="Button1" runat="server" Text="登录" onclick="Button1_Click" /> </form> </body> </html>
这里的按钮绑定了一个"onclick"事件,此事件是服务端事件,用C#来处理,代码如下:
protected void Button1_Click(object sender, EventArgs e) { String ID = id.Text; string PWD = pwd.Text; //...进行登录信息判断 }
在这里我们并没有编写HTML表单,也没有进行服务端Request的表单信息提取,而是直接通过控件对象id即可进行页面与服务端的数据交互。但是我们来分析一下最终呈现在客户端的HTML页面代码,发现一切还是老样子,如下:
<html> <head><title> 用户登录 </title></head> <body> <form name="form1" method="post" action="Default.aspx" id="form1"> <div> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTExNTc2NTI3OTlkZDhAU2pqwGz9QIwvDJiLphmcL2bd" /> </div> 账号:<input name="id" type="text" id="id" /><br /> 密码:<input name="pwd" type="password" id="pwd" /><br /> <input type="submit" name="Button1" value="登录" id="Button1" /> <div> <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWBAK13NjaCALH75rvDALGmdGVDAKM54rGBoZyLV3RTodafTBWGr2AaTw2+b29" /> </div></form> </body> </html>
ASP.NET生成的HTML内容,还是包括了form和input等基本HTML表单元素,以及相关表单属性,如表单的method和action等,只是这里的action是此ASP.NET页面自身的地址。
这里其实是ASP.NET做了一个客户端页面和服务端组件的对应组件模型。在生成页面的时候,服务端生成一个必要的组件信息代码,存放在生成的HTML代码中,用hidden隐藏表单字段保存。当页面通过表单的方式提交到服务端时,服务端解析出组件对象,根据服务端的事件处理和组件属性进行操作处理,屏蔽了一些HTML表单组件信息通过Request对象获取的底层逻辑。
当我们使用Ajax技术进行数据交互时,突破了传统的表单页面提交的方式。无论数据是存储在一个表单元素,或是一个DIV,或是一个JS变量,只要在Ajax请求时,将数据作为交互参数配置好,即可发送到服务端。
如下代码,是使用Edo.util.Ajax组件与服务端无刷新交互的标准代码:
Edo.util.Ajax.request({ url: 'login.aspx', //发送到一个登录页 type: 'post', //使用Post方式,发送的数据可以突破255个字符限制 params: { //发送的数据对象,可以是一个复杂对象 id: document.getElementById('id').value, //账号 pwd: document.getElementById('pwd').value, //密码 mem: document.getElementById('mem').checked //记住我? }, onSuccess: function(text){ //交互成功, 处理从服务端返回的字符串(一般是一个JSON) }, onFail: function(code){ //交互失败, 这里一般是物理错误, 比如404等 } });
上节服务端处理表单提交的代码,同样适合处理本节Ajax提交的数据。
这里对比了表单提交和Ajax交互两种方式的编程实现,基本上界面显示代码是一样的,区别在于数据提交时,是依赖HTML表单天然的提交功能(页面刷新),还是使用Ajax无刷新数据交互方式,从而获得更好的用户体验和编程控制。
本篇并不准备详细讲解Ajax技术的使用和配置属性,更多Edo.util.Ajax内容,请访问这里。
JSON无疑是最适合http传输协议下进行传输的数据格式了,体积小、易阅读、与JS无缝结合,因为一个JS Object或Array对象本身就是JSON格式。
数据在HTTP协议下传输的时候,它是以字符串的形式存在的。所以我们需要将客户端的JS对象,以及服务端的C#、JAVA、PHP、ASP等对象转换成JSON格式的字符串,相互序列化和反序列化。
比如我们现在有一个JS对象,存放用户登录信息,如下:
var loginObj = { id: 'edojs', pwd: '123456', mem: true };
现在我们需要将它转换成字符串(当然是JSON格式的),以便使用AJAX传输,并能方便转换成服务端对象:
var json = Edo.util.JSON.encode(loginObj);
得到的JSON字符串如下,跟JS对象的格式是一样的:
{"id": 'edojs',"pwd": '123456',"mem": true}
在ASP.NET平台,我们可以如下接受AJAX发送的数据,并将它转换为服务端对象(Hashtable和ArrayList):
String json = Request["loginInfo"]; //将JSON字符串,一次性转换为C#对象 Hashtable loginInfo = Edo.util.JSON.decode(json); //得到准确的参数变量,方便进行后续操作 String id = Convert.ToString(loginInfo["id"]); String pwd = Convert.ToString(loginInfo["pwd"]); Boolean mem = Convert.ToBoolean(loginInfo["mem"]);
String json = request.getParameter("loginInfo").toString(); //将JSON字符串,一次性转换为JAVA对象 Map loginInfo = (Map)Edo.util.JSON.decode(json); //得到准确的参数变量,方便进行后续操作 String id = loginInfo.get("id").toString(); String pwd = loginInfo.get("pwd").toString(); bool mem = new Boolean(loginInfo.get("mem").toString());
通过使用Edo.util.JSON,无论在客户端还是服务端,无论是Javascript,还是C#或JAVA,都能使用encode和decode两个函数轻松实现不同平台之间的对象传递。
EdoJS使用IBatis作为JAVA和.NET后台的数据交互层,可以轻松做到跨服务端平台和跨数据库的数据库操作。
关于Ibatis的介绍和使用,请访问Ibatis官网,并推荐几篇中文翻译。
我们提供了JSON序列化、Ajax交互、Ibatis操作数据库的示例,并且包含使用EdoJS表单和表格CURD(增/删/改/查)的完整演示,帮助开发者学习和了解界面与数据服务分离的开发模式,快速入门、轻松掌握。
这里下载EdoSamples