======================================================
注:本文源代码点此下载
======================================================
七、ajax开发
到这里,已经可以清楚的知道ajax是什么,ajax能做什么,ajax什么地方不好。如果你觉得ajax真的能给你的开发工作带来改进的话,那么继续看看怎么使用ajax吧。
7.1、ajax应用到的技术
ajax涉及到的7项技术中,个人认为javascript、xmlhttprequest、dom、xml比较有用。
a、xmlhttprequest对象
xmlhttprequest是xmlhttp组件的对象,通过这个对象,ajax可以像桌面应用程序一样只同服务器进行数据层面的交换,而不用每次都刷新界面,也不用每次将数据处理的工作都交给服务器来做;这样既减轻了服务器负担又加快了响应速度、缩短了用户等待的时间。
ie5.0开始,开发人员可以在web页面内部使用xmlhttp activex组件扩展自身的功能,不用从当前的web页面导航就可以直接传输数据到服务器或者从服务器接收数据。,mozilla1.0以及netscape7则是创建继承xml的代理类xmlhttprequest;对于大多数情况,xmlhttprequest对象和xmlhttp组件很相似,方法和属性类似,只是部分属性不同。
xmlhttprequest对象初始化:
xmlhttprequest对象的方法:
方法
描述
abort()
停止当前请求
getallresponseheaders()
作为字符串返回完整的headers
getresponseheader("headerlabel")
作为字符串返回单个的header标签
open("method","url"[,asyncflag[,"username"[, "password"]]])
设置未决的请求的目标 url,方法,和其他参数
send(content)
发送请求
setrequestheader("label", "value")
设置header并和请求一起发送
xmlhttprequest对象的属性:
属性
描述
onreadystatechange
状态改变的事件触发器
readystate
对象状态(integer):
0 = 未初始化
1 = 读取中
2 = 已读取
3 = 交互中
4 = 完成
responsetext
服务器进程返回数据的文本版本
responsexml
服务器进程返回数据的兼容dom的xml文档对象
status
服务器返回的状态码, 如:404 = "文件未找到" 、200 ="成功"
statustext
服务器返回的状态文本信息
b、javascript
javascript一直被定位为客户端的脚本语言,应用最多的地方是表单数据的校验。现在,可以通过javascript操作xmlhttprequest,来跟数据库打交道。
c、dom
dom(document object model)是提供给html和xml使用的一组api,提供了文件的表述结构,并可以利用它改变其中的内容和可见物。脚本语言通过dom才可以跟页面进行交互。web开发人员可操作及建立文件的属性、方法以及事件都以对象来展现。比如,document就代表页面对象本身。
d、xml
通过xml(extensible markup language),可以规范的定义结构化数据,是网上传输的数据和文档符合统一的标准。用xml表述的数据和文档,可以很容易的让所有程序共享。
7.2、ajax开发框架
这里,我们通过一步步的解析,来形成一个发送和接收xmlhttprequest请求的程序框架。ajax实质上也是遵循request/server模式,所以这个框架基本的流程也是:对象初始化à发送请求à服务器接收à服务器返回à客户端接收à修改客户端页面内容。只不过这个过程是异步的。
a、初始化对象并发出xmlhttprequest请求
为了让javascript可以向服务器发送http请求,必须使用xmlhttprequest对象。使用之前,要先将xmlhttprequest对象实例化。之前说过,各个浏览器对这个实例化过程实现不同。ie以activex控件的形式提供,而mozilla等浏览器则直接以xmlhttprequest类的形式提供。为了让编写的程序能够跨浏览器运行,要这样写:
if (window.xmlhttprequest) { // mozilla, safari, ...
http_request = new xmlhttprequest();
}
else if (window.activexobject) { // ie
http_request = new activexobject("microsoft.xmlhttp");
}
有些版本的mozilla浏览器处理服务器返回的未包含xml mime-type头部信息的内容时会出错。因此,要确保返回的内容包含text/xml信息。
http_request = new xmlhttprequest();
http_request.overridemimetype('text/xml');b、指定响应处理函数
接下来要指定当服务器返回信息时客户端的处理方式。只要将相应的处理函数名称赋给xmlhttprequest对象的onreadystatechange属性就可以了。比如:
http_request.onreadystatechange = processrequest;
需要指出的时,这个函数名称不加括号,不指定参数。也可以用javascript即时定义函数的方式定义响应函数。比如:
http_request.onreadystatechange = function() { };
c、发出http请求
指定响应处理函数之后,就可以向服务器发出http请求了。这一步调用xmlhttprequest对象的open和send方法。
http_request.open('get', 'http://www.example.org/some.file', true);
http_request.send(null);
open的第一个参数是http请求的方法,为get、post或者head。
open的第二个参数是目标url。基于安全考虑,这个url只能是同网域的,否则会提示“没有权限”的错误。这个url可以是任何的url,包括需要服务器解释执行的页面,不仅仅是静态页面。目标url处理请求xmlhttprequest请求则跟处理普通的http请求一样,比如jsp可以用request.getparameter(“”)或者request.getattribute(“”)来取得url参数值。
open的第三个参数只是指定在等待服务器返回信息的时间内是否继续执行下面的代码。如果为true,则不会继续执行,直到服务器返回信息。默认为true。
按照顺序,open调用完毕之后要调用send方法。send的参数如果是以post方式发出的话,可以是任何想传给服务器的内容。不过,跟form一样,如果要传文件或者post内容给服务器,必须先调用setrequestheader方法,修改mime类别。如下:
http_request.setrequestheader(“content-type”,”application/x-www-form-urlencoded”);
这时资料则以查询字符串的形式列出,作为sned的参数,例如:
name=value&anothername=othervalue&so=ond、处理服务器返回的信息
在第二步我们已经指定了响应处理函数,这一步,来看看这个响应处理函数都应该做什么。
首先,它要检查xmlhttprequest对象的readystate值,判断请求目前的状态。参照前文的属性表可以知道,readystate值为4的时候,代表服务器已经传回所有的信息,可以开始处理信息并更新页面内容了。如下:
if (http_request.readystate == 4) {
// 信息已经返回,可以开始处理
} else {
// 信息还没有返回,等待
}
服务器返回信息后,还需要判断返回的http状态码,确定返回的页面没有错误。所有的状态码都可以在w3c的官方网站上查到。其中,200代表页面正常。
if (http_request.status == 200) {
// 页面正常,可以开始处理信息
} else {
// 页面有问题
}
xmlhttprequest对成功返回的信息有两种处理方式:
responsetext:将传回的信息当字符串使用;
responsexml:将传回的信息当xml文档使用,可以用dom处理。
e、一个初步的开发框架
总结上面的步骤,我们整理出一个初步的可用的开发框架,供以后调用;这里,将服务器返回的信息用window.alert以字符串的形式显示出来:
7.3、简单的示例
接下来,我们利用上面的开发框架来做两个简单的应用。
a、数据校验
在用户注册的表单中,经常碰到要检验待注册的用户名是否唯一。传统的做法是采用window.open的弹出窗口,或者window. showmodaldialog的对话框。不过,这两个都需要打开窗口。采用ajax后,采用异步方式直接将参数提交到服务器,用window.alert将服务器返回的校验信息显示出来。代码如下:
在之间增加一段form表单代码:
用户名:
在开发框架的基础上再增加一个调用函数:
function usercheck() {
var f = document.form1;
var username = f.username.value;
if(username=="") {
window.alert("用户名不能为空。");
f.username.focus();
return false;
}
else {
send_request('sample1_2.jsp?username='+username);
}
}
看看sample1_2.jsp做了什么:
运行一下,嗯,没有弹出窗口,没有页面刷新,跟预想的效果一样。如果需要的话,可以在sample1_2.jsp中实现更复杂的功能。最后,只要将反馈信息打印出来就可以了。
b、级联菜单
我们在第五部分提到利用ajax改进级联菜单的设计。接下来,我们就演示一下如何“按需取数据”。
首先,在中间增加如下html代码:
在框架的基础上增加一个响应函数showroles(obj):
//显示部门下的岗位
function showroles(obj) {
document.getelementbyid(obj).parentnode.style.display = "";
document.getelementbyid(obj).innerhtml = "正在读取数据..."
currentpos = obj;
send_request("sample2_2.jsp?playpos="+obj);
}
修改框架的processrequest函数:
// 处理返回信息的函数
function processrequest() {
if (http_request.readystate == 4) { // 判断对象状态
if (http_request.status == 200) { // 信息已经成功返回,开始处理信息
document.getelementbyid(currentpos).innerhtml = http_request.responsetext;
} else { //页面不正常
alert("您所请求的页面有异常。");
}
}
}
最后就是smaple2_2.jsp了:
运行一下看看效果:
7.4、文档对象模型(dom)
文档对象模型(dom)是表示文档(比如html和xml)和访问、操作构成文档的各种元素的应用程序接口(api)。一般的,支持javascript的所有浏览器都支持dom。本文所涉及的dom,是指w3c定义的标准的文档对象模型,它以树形结构表示html和xml文档,定义了遍历这个树和检查、修改树的节点的方法和属性。
7.4.1、dom眼中的html文档:树
在dom眼中,html跟xml一样是一种树形结构的文档,是根(root)节点,
供读取调用的xml文档 – employees.xml:
programmer
32768
sales
70000
ceo
100000
7.5、处理xml文档
脱离xml文档的ajax是不完整的。在本部分未完成之前,有读者说ajax改名叫ajah(h应该代表html吧)比较合适。应该承认,xml文档在数据的结构化表示以及接口对接上有先天的优势,但也不是所有的数据都应该用xml表示。有些时候单纯的文本表示可能会更合适。下面先举个ajax处理返回xml文档的例子再讨论什么时候使用xml。
7.5.1、处理返回的xml
例子8 -- sample7_1.htm:
在这个例子中,我们采用之前确定的ajax开发框架,稍微修改一下body内容和processrequest的相应方式,将先前的employees.xml的内容读取出来并显示。
body的内容如下:
processrequest()方法修改如下:
// 处理返回信息的函数
function processrequest() {
if (http_request.readystate == 4) { // 判断对象状态
if (http_request.status == 200) { // 信息已经成功返回,开始处理信息
var returnobj = http_request.responsexml;
var xmlobj = http_request.responsexml;
var employees = xmlobj.getelementsbytagname("employee");
var feedbackstr = "";
for(var i=0;i
运行一下,看来效果还不错:
7.5.2、选择合适的xml生成方式
现在的web应用程序往往采用了mvc三层剥离的设计方式。xml作为一种数据保存、呈现、交互的文档,其数据往往是动态生成的,通常由javabean转换过来。由javabean转换成xml文档的方式有好几种,选择合适的转换方式往往能达到事半功倍的效果。下面介绍两种常用的方式,以便需要的时候根据情况取舍。
a、类自行序列化成xml
类自行序列化成xml即每个类都实现自己的toxml()方法,选择合适的api、适当的xml结构、尽量便捷的生成逻辑快速生成相应的xml文档。显然,这种方式必须要求每个类编写专门的xml生成代码,每个类只能调用自己的toxml()方法。应用诸如jdom等一些现成的api,可以减少不少开发投入。例子9是一个利用jdom的api形成的toxml()方法。
例子9 -- toxml() 的 jdom 实现 -- employ类的toxml()方法:
public element toxml() {
element employee = new element(“employee”);
employee.setattribute(“name”,name);
element jobe = new element(“job”).addcontent(job);
employee.setcontent(jobe);
element salarye = new element(“salary”).addcontent(salary);
employee.setcontent(salarye);
return employee;
}
jdom提供了现成的api,使得序列化成xml的工作更加简单,我们只需要把toxml()外面包装一个document,然后使用xmloutputter把文档写入servlet就可以了。toxml()允许递归调用其子类的toxml()方法,以便生成包含子图的xml文档。
使用类自行序列化成xml的方式,要每个类都实现自己的toxml()方法,而且存在数据模型与视图耦合的问题,即要么为每个可能的视图编写独立的toxml()方法,要么心甘情愿接收冗余的数据,一旦数据结构或者文档发生改变,toxml()就要做必要的修改。
b、页面模板生成xml方式
一般的,可以采用通用的页面模板技术来生成xml文档,这个xml文档可以符合任何需要的数据模型,供ajax灵活的调用。另外,模板可以采用任何标记语言编写,提高工作效率。下面是一个采用struts标签库编写的xml文档,输出之前提到的employees.xml:
sample8_2.jsp:
">
采用页面模板生成xml方式,需要为每个需要的的数据模型建立一个对立的jsp文件,用来生成符合规范的xml文档,而不能仅仅在类的toxml()方法中组织对象图来实现。不过,倒是可以更加方便的确保标记匹配、元素和属性的顺序正确以及xml实体正确转义。
参考资料中philip mccarthy的文章还描述了一种javascript对象标注的生成方式,本文在此不赘述。有兴趣的读者可以自行查看了解。
7.5.3、如何在使用xml还是普通文本间权衡
使用xml文档确实有其方便之处。不过xml文档的某些问题倒是要考虑一下,比如说延迟,即服务器不能立即解析xml文档成为dom模型。这个问题在一定程度上会影响ajax要求的快速反应能力。另外,某些情况下我们并不需要使用xml来表示数据,比如说数据足够简单成只有一个字符串而已。就好像我们之前提到的数据校验和级联菜单的例子一样。所以,个人认为在下面这些情况下可以考虑使用xml来作为数据表示的介质:
数据比较复杂,需要用xml的结构化方式来表示
不用考虑带宽和处理效率支出
与系统其他api或者其他系统交互,作为一种数据中转中介
需要特定各式的输出视图而文本无法表示的
总之,要认真评估两种表示方式的表示成本和效率,选择合适的合理的表示方式。
在关于ajax的系列文章的下一篇,我们将综合使用dom和xml,来实现一个可以持久化的简单留言簿。另外,还将试着模拟msn space的部分功能,来体会ajax的魅力。
参考文章:
作者:
fanscial
标题:
《ajax简介》
网址:
http://www.blogjava.net/fanscial/archive/2005/08/31/11628.html
作者:
amour guo
标题:
《ajax内部交流文档》
网址:
http://www.dragonson.com/doc/ajax.html
作者:
moztwwiki
标题:
《ajax上手篇》
网址:
http://wiki.moztw.org/index.php/ajax_%e4%b8%8a%e6%89%8b%e7%af%87
作者:
philip mccarthy
标题:
面向java开发人员的ajax:构建动态的java应用程序
网址:
http://kb.youkuaiyun.com/java/articles/200510/bed0423e-5297-49c9-9464-0e3eb733c8b5.html
作者:
philip mccarthy
标题:
面向java开发人员的ajax:ajax的java对象序列化
网址:
http://kb.youkuaiyun.com/java/articles/200510/a5b630cf-a2c2-46f1-8e3b-eadde723e734.html
作者:
david flanagan
书名:
《javascript权威指南》
opendoc版权说明:
本文档版权归原作者所有。
在免费、且无任何附加条件的前提下,可在网络媒体中自由传播。
如需部分或者全文引用,请事先征求作者意见。
如果本文对您有些许帮助,表达谢意的最好方式,是将您发现的问题和文档改进意见及时反馈给作者。当然,倘若有时间和能力,能为技术群体无偿贡献自己的所学为最好的回馈。
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/