一、 简介
异步javascript+xml(即ajax),是一种创建交互式web应用程序的技术。这种程序使用javascript和xml从客户端提交服务器请求,且整个过程中仅需要交换少量的数据而不必提交整个web页面。因此,这样的程序将更快和更具响应性,并将成为新一代客户机-服务器系统的重要基础技术之一。你可以在站点http://www.google.com/webhp?complete=1&hl=en处看到一种良好的ajax实践技术展示。在此页面中,如果你把任何字母输入到文本框内,那么随后就会出现一个下拉列表框,其中的内容直接来自于服务器而不必提交整个页面。ajax的核心是xmlhttprequest对象。客户端能够在后台检索并直接提交xml数据。为了把检索的xml数据转换成可生成的html内容,需要依赖于客户端文档对象模型(dom)读取xml文档结点树并且组成用户看得见的html元素。其实,ajax并非象html,dhtml等一样的单一技术,它结合了不同的技术:
·xmlhttprequest对象被使用于与web服务器异步地交换数据。
·xml被普遍用作把数据传输回服务器的格式(尽管任何格式都能使用,例如普通文本,html等)。
·如果使用xml作为转换格式,那么dom通常与如javascript这样的客户端脚本语言一起使用来动态地显示和描述交互信息。
·xhtml(或html),css用于标记和信息格式化。
二、 xmlhttprequest对象
从历史来看,是微软首先在其internet explorer 5 for windows中以一个activex对象形式实现了xmlhttprequest对象。随后,由mozilla工程的工程师实现了mozilla 1.0(和netscape 7)的一种兼容的本机版本;而稍后,苹果公司在其safari 1.2上也实现了相同的工作。其实,在w3c标准的文档对象模型(dom)level 3加载与存储规范中,也提到了类似的功能。现在,它成为一种事实上的标准,并开始在以后发行的大多数浏览器中得到实现。
(一) 创建对象
xmlhttprequest对象的创建方式因浏览器不同而有所不同。对于safari和mozilla来说,其创建方式如下所示:
var req = new xmlhttprequest();
对于internet explorer 5.0+(指5.0及更高版本),则要把对象名传递到activex构造函数中:
var req = new activexobject("microsoft.xmlhttp");
该对象的方法控制所有的操作,而其属性存储从服务器返回的各种数据片断,例如xmlhttpobject.responsetext包含从服务器返回的xml或字符串值。
(二) 方法
在windows ie 5.0+、safari 1.2和mozila中支持的xmlhttprequest对象的方法列举如下:
方法 | 描述 |
abort() | 取消当前的请求。如果你在一个不处理请求(readystate 0或4)的对象上调用它,"神秘的事情"发生了。 |
getresponseheader("headerlabel") | 返回单个头标签的字符串值 |
getallresponseheaders() | 以一个串形式返回完整的头(标签和值)集合 |
open("method","url"[,asyncflag[, "username"[,"password"]]]) | 指派目标url、方法及一个悬挂请求的其它可选属性 |
send(content) | 传输请求。(可选择地)其中可以加入可寄送的字符串或dom对象数据 |
setrequestheader("label","value") | 把一个标签/值对指派给要发送的请求中的头部 |
在上面的方法中,open和send方法是最重要的。下面,让我们首先从应用程序的观点来讨论open方法。
var req;
………………………
req = new activexobject("microsoft.xmlhttp");
……………
var url="ajaxserver.aspx?pubid="+id;
……………
//打开一个到url的get请求
req.open("get",url,true);
//实际发送一个空请求
req.send(null);
注意
在这个示例应用程序中,ajaxclient.aspx页面是用户接口,ajaxserver.aspx则负责提供每一个用户请求时的数据。要特别注意的是,ajaxserver.aspx页面不应该包含任何html。你可以测试一下如果页面包含html将会发生什么。
open方法的第一个参数(见上面表格中的open函数)指示当前操作为一个get操作或是post操作。在进行简单的数据检索时,一般使用get。当向外传输的数据包大于512字节且操作包括服务器端活动(如插入,更新等)时,一般使用post。接下来,我们看一下"url"参数。这个参数可以是一个完整的url也可以是一个相对url。在上面例子中,使用的是相对的url。"asyncflag"参数指示在执行send方法后是否立即处理到来的脚本(这意味着不必等待是否有响应)。最后两个参数分别是"username"和"password",如果"url"中提供这些数据的话。
另一个重要的方法是send方法,它实际上使用一个消息体发送请求。对于本例而言,它只是发送一个空请求。
[
//实际发送一个空请求
req.send(null);
]
(三) 属性
属性 | 描述 |
onreadystatechange | 每当状态改变时激发的事件的事件处理器。其中,readystate对象状态整数含义如下:0=uninitialized1=loading2=loaded3=interactive4=complete |
responsetext | 经服务器处理后返回的数据的字符串版本 |
responsexml | 经服务器处理后返回的dom兼容的数据文档对象 |
status | 由服务器返回的数字代码,例如404代表"not found",200代表"ok" |
statustext | 伴随着状态代码的字符串信息 |
在此,应用程序中使用了onreadystatechange:
//这是事件处理器机制;在本例中,"requestprocessor"即是事件处理器。
req.onreadystatechange=requestprocessor;
对于这个应用程序来说,"requestprocessor"是客户端的事件处理器。现在,在事件处理器内,使用readystate属性来获得各种状态。值4显示已经完成某种处理。现在,在处理结果前,你应该检查状态或statustext以决定操作成功与否。在这个应用程序中,我是以下面方式实现的:
function requestprocessor()
{
//如果readystate处理"ready"状态
if(req.readystate == 4)
{
//返回的状态代码200意味着一切顺利
if(req.status == 200)
{
//如果responsetext不空
//req.responsetext实际上是一个由ajaxserver.aspx的"response.write("" + sbxml.tostring() + "");"方法编写的字符串
if(req.responsetext != "")
{
populatelist(req.responsexml);
}
else
{
clearselect(publishedbooks);
}
}
}
return true;
}
注意 对象req被声明为一个页面级的变量:
var req = new activexobject("microsoft.xmlhttp");
警告
请求目的的url必须与客户端脚本处于同一个域中。原因是,xmlhttprequest对象采用与客户端脚本一致的封装技术。在大多数支持这种功能的浏览器上,拥有存取xmlhttprequest对象的脚本的页面都需要使用http:协议检索。这意味着,你无法在一个本地硬盘上(file:协议)进行页面测试。 三、 实际问题
在ajax中,如果网络或远程服务器出现中断,会发生什么呢?实际上,存在两个主要问题;默认地,它们并没有在xmlhttprequest对象中得到解决。这两个主要问题是:
1.处理延迟:如果网络或远程服务器耗费较多时间,那么这个问题如何与你的ajax应用程序相联系呢?
2.响应顺序:潜在地,网络(或服务器)会不断变化。这意味着,响应可能不会以与请求相同的顺序返回。
为了处理上面这两个问题,程序员必须编写代码来解决这个问题。对于第一个问题,一种可能的方案如下所示:
function callinprogress(xmlhttp) {
switch ( xmlhttp.readystate ) {
case 1,2,3:
return true;
break;
//case 4和0
default:
return false;
break;
}
}
现在,在调用send()前,我可以先检查一下是否该对象正处于忙态:
if ( !callinprogress(xmlhttp) ) {
xmlhttp.send(null);
} else {
alert("i'm busy. wait a moment");
}
(一) 支持ajax技术的浏览器
·微软internet explorer版本5.0及以上版本,和基于它的浏览器(mac os版本不支持)
·基于gecko的浏览器,如mozilla,mozilla firefox,seamonkey,epiphany,galeon和netscape版本7.1及以上版本
·实现khtml api版本3.2及以上版本的浏览器,包括konqueror版本3.2及以上版本,还有apple safari版本1.2及以上版本
·opera浏览器版本8.0及以上版本,包括opera mobile浏览器版本8.0及以上版本
(二) 不支持ajax技术的浏览器
·opera 7及以下版本
·微软internet explorer 4.0及以下版本
·基于文本的浏览器,如lynx和links
·没有可视化实现的浏览器
·1997年以前的浏览器
(三) 本文示例应用程序特定需求
软件要求:
1.asp.net 2.0;
2.ms sql server 2000,并要求相应的pubs数据库设置;
3.改变web.config文件中的db连接字符串("conn_string"键)。
<appsettings>
<add value="data source=cal-slcu2-196;database=pubs;user=sa;pwd=sa" key="conn_string" />
</appsettings>
变量或类名应该象上面这样被包括到<code>标记中。
四、 总结
本文概括性地归纳了基于ajax技术构建下一代流行web应用程序的主要技术及有关概念,并给出一个完整示例程序的关键片断的分析。