用AJAX开发智能Web应用程序之基础篇(1)


一. 什么是AJAX?

这个名字代表了异步JavaScript+XMLHTTPRequest,并且意味着你可以在基于浏览器的JavaScript和服务器之间建立套接字通讯。其实AJAX并不是一种新技术,而是已经成功地用于现代浏览器中的若干成功技术的可能性组合。

所有的AJAX应用程序实现了一种“丰富的”UI——这是通过JavaScript操作HTML文档对象模型并且经由XMLHttpRequest实现的精确定位的数据检索来实现的。典型的示例AJAX应用程序是Google Labs(http://labs.google.com)的Google Maps和Google Suggest。这些应用程序现场监视用户输入并且提供实时的页面更新。最重要的是,在用户通过地图导航或输入一个查找字符串的同时,这些事件不需要刷新页面。

事实上,支持这些令人感到惊讶的应用的技术已经出现一段时间了,尽管它们要求复杂的技能以及使用浏览器的技巧。一些专利产品就提供了相似的能力——如Macromedia Flash插件,Java Applets或.NET运行时——在达到实用上已经有一段时间了。把一种可与服务器通话的脚本组件引入到浏览器中的思想早在IE 5.0中就已经存在。Firefox和其它流行的浏览器也加入到浏览器大军中并以一种内置对象形式支持XMLHTTPRequest。随着跨平台浏览器的出现,这些技术得到了认可并在2004年3月一家称为Adaptive Path的公司中正式提出了AJAX。

简而言之,由于来自于Google的支持和安装了一点可用的浏览器技术,加上为了一种"更好的用户体验",每个人都在把客户端技术添加到Web应用程序上。

二. AJAX与传统应用程序的区别

一个传统Web应用程序模型实际上是一种基本的事件——用户被迫提交表单以实现页面交换。也就是说,表单提交和页面传送无法得到保证:还有更坏的情形——用户需要再次点击。这与AJAX截然不同-——数据跨过线路而不是完整的HTML页面传输。这种数据交换是经由特定的浏览器对象:XMLHttpRequest实现的;再由适当的逻辑来处理每个数据请求的结果,页面的特定区域而不是完整的页面被更新。结果是更快的速度,更少的拥挤和更好的信息传送控制。

传统型"click-refresh"Web应用程序强迫用户中断工作过程而等待页面的重装。通过引入AJAX技术,一个客户端脚本能够异步地与服务器通话,而用户仍能保持输入数据。除了对用户透明之外,这样的异步意味着服务器可以有更多时间来处理请求。

传统Web应用程序把所有的处理代理到服务器并且强迫服务器进行状态管理。AJAX允许灵活划分应用程序逻辑以及客户和服务器之间的状态管理。这就消除了一种"click-refresh"依赖性并且提供更好的服务器可伸缩性。当该状态存储在客户端,你就不必跨越服务器来维持会话或保存/结束状态-其使用期限是由客户端来定义的。

三. AJAX——分布式的MVC

尽管AJAX应用程序依靠JavaScript来实现描述层,然而处理能力和知识库仍然存在于服务器上。此时,AJAX应用程序大量的与J2EE服务器通讯——把数据输入/输出Web服务和servlets。具有基于AJAX的描述层的J2EE应用程序和标准J2EE应用程序之间的区别首先在于,MVC是通过线路分布的。通过使用AJAX,视图是本地的,而模型和控制器是分布式的——这使得开发者能够灵活地决定哪些部件会是基于客户端的。具体地说,本地视图通过巧妙地操作HTML DOM而生成图形;控制器局部地处理用户输入并且根据开发者的判断扩展到服务器的处理——经由HTTP请求(Web服务,XML/RPC或其它)实现;模型的远程部分是根据客户端需要而下载的以达到实时更新客户端页面;并且状态是在客户端收集的。

在以后的AJAX文章中,我们将比较深入地讨论这里的每一种组件并提供有关它们联合在一起进行应用的示例。现在,先不多说,让我们详细地分析一个简单的AJAX示例。

四. 邮政区号校验和查询

我们将创建一个包含三个INPUT字段(Zip,City和State)的HTML页面。我们将保证,只要用户输入邮政区号的前三个数字,该页面上的字段就会用第一个匹配的状态值填充。一旦用户输入了所有五位邮政区号数,我们将立即决定和填充相应的城市。如果邮政区号无效(在服务器的数据库没有找到),那么我们将把邮政区号的边界设置为红色。这样的可视化线索有助于用户并且在现代浏览器中已经成为一种标准(作为一实例,当Firefox找到一个HTML页面中的匹配关键字时,它会高亮与你在浏览器查找域输入的内容一致的部分)。

让我们首先创建一个简单的包含三个INPUT字段的HTML:zip,city和state。请注意,一旦一个字符输入进邮政区号字段域中,即调用方法zipChanged()。JavaScript函数zipChanged()(见下)在当zip长度为3时调用函数updateState(),而在当zip长度为5时调用函数up-dateCity()。而updateCity()和updateState()把大部分的工作代理到另一个函数ask()。

Zip:<input id="zipcode" type="text" maxlength="5" onKeyUp="zipChanged()"

style="width:60"/>

City: <input id="city" disabled maxlength="32" style="width:160"/>

State:<input id="state" disabled maxlength="2" style="width:30"/>

<script src="xmlhttp.js"></script>

<script>

var zipField = null;

function zipChanged(){

zipField = document.getElementById("zipcode")

var zip = zipField.value;

zip.length == 3?updateState(zip):zip.length == 5?updateCity(zip):"";

}

function updateState(zip) {

 var stateField = document.getElementById("state");

 ask("resolveZip.jsp?lookupType=state&zip="+zip, stateField, zipField);

}

function updateCity(zip) {

 var cityField = document.getElementById("city");

 ask("resolveZip.jsp? lookupType=city&zip="+zip, cityField, zipField);

}

</script> 


函数ask()与服务器进行通讯并分配一个回调函数来处理服务器的响应(见下列代码)。后面,我们将分析具有双重特点的resolveZip.jsp的内容-它根据zip字段中的字符数查找city或state信息。重要的是,ask()使用了具有异步特点的XmlHttpRequest,这样填充state和city字段或着色zip字段边界就可以不必减慢数据入口而得以实现。首先,我们调用request.open()-它用服务器打开套接字频道,使用一个HTTP动词(GET或POST)作为第一个参数并且以数据提供者的URL作为第二个参数。request.open()的最后一个参数被设置为true-它指示该请求的异步特性。注意,该请求还没有被提交。随着对request.send()的调用,开始提交-这可以为POST提供任何必要的有效载荷。在使用异步请求时,我们必须使用request.onreadystatechanged属性来分配请求的回调函数。(如果请求是同步的话,我们应该能够在调用request.send之后立即处理结果,但是我们也有可能阻断用户,直到该请求完成为止。)

本文作者:
« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3