掌握Ajax,第一部分,Ajax简介

时间:2021-10-31 20:45:29
原文:
生产实践课要求翻译一篇文章,我选择了这篇介绍Ajax的,原文在这里
http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html

译文:

Ajax——包括HTML,Javascript,DHTML和DOM——是帮助把沉闷的Web界面变为交互式界面的卓越的方法。

五年前, 如果你不知道XML,没有人会和你交谈,你太土了;十八个月前,如果你不知道崭露头角的Ruby,那么你无法融入程序员的圈子。今天,如果你想知道什么是新的技术热点,毫无疑问,就是Ajax。

然而Ajax远不仅仅是一波时尚—它是建立网站的强有力的工具,几乎不比一种新的程序语言难学。

在我深入讨论Ajax之前,让我们先来看一下Ajax能做哪些事情。今天的程序,无外乎两种:
  桌面应用程序
  Web应用程序
它们并不陌生。桌面程序通常来自一张CD(或者从网站下载),在你的计算机上安装。也许它们通过Internet来更新,但是运行程序的代码是驻留在本地计算机上的。Web应用程序——这并不令人吃惊——运行在服务器上并通过浏览器来访问。

但是,比运行在何处更重要的,是程序如何运行以及如何与人交互。桌面程序通常非常快(它们运行在你的计算机,不需要等待网络连接),强大的交互功能(通常是和操作系统交互),动态效果非常出色。你可以点击、指向、输入、拉出菜单、子菜单,或者四处逛逛,这些都不需要等待。

另一方面,Web程序提供了桌面上从未有过的服务(想想Amazon.com和eBay.com)。然而强大的Web也带来了等待——等待来自服务器的回应,等待屏幕的刷新,等待请求的返回,等待新页面的生成。

上面简单的描述了两者的应用,提供你一个基本的概念。正如你已经开始怀疑的,Ajax试图连接两者的差距:桌面程序的功能性、交互性和Web程序的始终更新。

你可以在Web程序上使用动态的界面接口和有趣的控件,这些原先是桌面程序的“专利”。

还等什么?让我们来看看如何把乏味的Web程序变成Ajax程序。
———————————————————————————————————
老技术,新把戏

当我们开始谈及Ajax时,现实情况是Ajax牵涉到很多技术,要超越基本的了解,你需要深入了解各种技术。值得庆幸的是,也许你已经学了一些,至少比Java和Ruby容易。

下面是Ajax涉及的技术
    HTML用来建立Web form
    JavaScript是Ajax的核心技术,方便服务器和应用程序的通信。
    DHTML帮助动态更新form。你将使用div,span和其他动态HTML元素来标
记HTML。
   DOM通过JavaScript和从服务器返回的HTML或者XML一起工作。

下面让我们分别看一下它们是如何运作的。

XMLHttpRequest 对象
第一个亮相的是XMLHttpRequest,你或许是头一回见到。这是一个JavaScript对象,产生的方法如下。

LISTING1
<script language="javascript" type="text/javascript">
var xmlHttp = new XMLHttpRequest();
</script>

我将在下一篇文章中详细讲解这个对象,但是现在请记住,这个对象处理所有的服务器的通信。在进一步讨论之前,请仔细想一下:JavaScript贯串了XMLHttpRequest和服务器对话的过程,这是Ajax神奇的地方,不同于普通的程序流程。

普通的Web应用,用户填入form字段,然后点击提交按钮。然后整个form被送到服务器,服务器调用处理脚本的进程(PHP,Java,也许还包括CGI),当脚本执行完毕,服务器返回一个完整的新页面。页面也许包括含有数据的新form,或者是确认的页面,或者根据原form选择的选项。当然,程序或脚本在处理的时候,用户是必须等待的。屏幕将变为空白,当数据从服务器返回时重新绘制。所以,用户无法得到即时回馈,这和桌面应用程序的体验不同。

本质上Ajax把JavaScript和XMLHttpRequest对象介于Web form和服务器中间。当用户填写form时,数据被送入某些JavaScript代码而不是直接给服务器。

JavaScript抓住数据,向服务器发送请求。当这些发生的时候,用户界面不闪烁、消失或停止。换句话说,JavaScript在后台发送请求,用户不感觉到请求被发送。更好的情况下,请求被非同步的发送,JavaScript不等待服务器的返回。所以用户可以继续输入数据,或者做他想做的其它事情。

然后服务器返回数据给JavaScript(仍然在Web form中),由JavaScript代码决定怎样处理这些数据。代码可能更新了form field,让用户觉得没有提交或刷新就获得了新的数据。JavaScript代码还可以对数据做些计算再提交请求,这些都无需用户参与。这是XMLHttpRequest的强大功能。用户获得了动态、应答的(Responsive)、高交互的体验,就如桌面程序一样。

加一些JavaScript
获得了XMLHttpRequest后,JavaScript代码的工作就简单了,包括如下的几个任务:
    获得form数据。
    修改form上的数据。
    解析HTML和XML。
前两项,你需要熟悉getElementByID()函数,如下:

LISTING2
// Get the value of the "phone" field and stuff it in a variable called phone
var phone = document.getElementById("phone").value;

// Set some values on a form using an array called response
document.getElementById("order").value = response[0];
document.getElementById("address").value = response[1];

这里没有需要特别提的内容,这不难。当你掌握了XMLHttpRequest,剩下的工作就是如Listing2所示的JavaScript代码,还有些技巧型的HTML代码,偶尔的还有些DOM。

最后来看看DOM
DOM,即Document Object Model。DOM听上去很陌生,HTML设计者不常使用它,即使JavaScript程序员也只有在高端编程时涉及。在大型的Java和C/C++程序中常使用DOM,所以DOM似乎很难学。

幸运的是,在JavaScript中使用DOM很容易而且直观。这里,我将用例子展示如何使用DOM,但即使如此也可能会产生误导。你可以不使用DOM实现Ajax,这也是我想演示的方式。当在JavaScript和服务器传输XML并需要修改HTML form的时候,

可以再回头看DOM。现在更好的办法是看些不用DOM的Ajax例子。
——————————————————————————————————
获得请求对象
在有了大致的概念后,你将开始学习具体的内容。由于XMLHttpRequest是Ajax应用的核心,我将从它开始。正如在Listing1看到,这似乎很容易,是吗?先等一下下结论。

还记得几年前令人讨厌的浏览器大战吗?不管你是否相信,在小范围内,这场战争还在继续。XMLHttpRequest是这场战争的牺牲者之一。所以在获得XMLHttpRequest时你需要做些不同的事情。我将带你一步步来完成。

微软浏览器
微软的浏览器,Internet Explorer,使用MSXML来处理XML(你可以在文章最后的Resource中找到详细的资料)(见原文 ——译注) 。所以如果你打算写能够在IE上运行的Ajax应用,就需要用某些方法来生成对象。

MSXML有两个版本,依赖于在IE上安装的不同JavaScript版本,所以你的代码必须处理这两种情况。参考代码见下面的Listing3

LISTING3
var xmlHttp = false;
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}

在这一系列结束之前,你需要深入了解JavaScript编程、错误处理等等。现在你需要记住两行代码:
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");.
简单讲,这两行代码使用了某一版本的MSXML。如果两种方法都无效,变量xmlHttp将被置为false,这也意味着你遇到了非微软的浏览器,需要其它代码来处理。

Mozilla和其他非微软浏览器
如果是非微软浏览器,代码就简单了,如下:
var xmlHttp = new XMLHttpRequest object;.
这行代码适用的浏览器包括Mozilla, Firefox, Safari, Opera,和其他非微软浏览器。

整合在一起
当然你不希望代码只适用于微软的浏览器,也不想写两遍代码,那就把上面的代码整合在一起:

LISTING4
/* Create a new XMLHttpRequest object to talk to the Web server */
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_JavaScriptcript_version >= 5)
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}
@end @*/

if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
  xmlHttp = new XMLHttpRequest();
}
先忽略注释中的@cc_on,这是JavaScript编译器的特殊命令,我将在后面的文章中提及。
核心代码总共分成三步:
1:建立xmlHttp变量,作为XMLHttpRequest对象的引用(reference)
2:试图新建微软浏览器的对象
3:如果xmlHttp没有建立,就建立针对非微软浏览器的对象。

提一下安全
今天的浏览器允许用户提升安全等级,比如关闭JavaScript,或禁用其他的选项。这时,你的代码将必然无法运行。因此,你需要巧妙的处理这种情况,我将在后面的文章中谈到这个问题(这个系列看上去很长,不是吗?)。目前你的代码强劲但不完美。你将在后面看到细节的问题。
———————————————————————————————————
Ajax的请求和返回(Request/Response)
你已经学会了建立XMLHttpRequest对象。如果你看得仔细的话,你已经知道其实是JavaScript在和服务器对话,而不是提交HTML form。

还缺了什么呢?如何使用XMLHttpRequest。由于请求和返回是每一个Ajax应用都要使用的重要代码,因此让我们快速的浏览一下是有好处的。

发送请求
你手中有了新建的XMLHttpRequest。首先,你需要一个Web页面能调用的JavaScript函数,比如当用户输入字符或选择某个菜单的选项。然后,按照下面的基本框架来实现Ajax。
    从Web form获得任何你想要的数据
    建立欲连接的URL
    建立和服务器的连接
    设定服务器处理完请求后调用的函数
    发送请求
LISTING5是示例代码

Listing5
function callServer() {
  // Get the city and state from the web form
  var city = document.getElementById("city").value;
  var state = document.getElementById("state").value;
  // Only go on if there are values for both fields
  if ((city == null) || (city == "")) return;
  if ((state == null) || (state == "")) return;

  // Build the URL to connect to
  var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);

  // Open a connection to the server
  xmlHttp.open("GET", url, true);

  // Setup a function for the server to run when it's done
  xmlHttp.onreadystatechange = updatePage;

  // Send the request
  xmlHttp.send(null);
}


许多地方不言自明。开头的JavaScript代码获得了form中的一些值。然后把某一PHP脚本文件作为欲连接的目标URL。注意URL是如何定义的。再使用简单的GET方式把city和state添加到URL中。

接下来,一个连接开启了。这里你第一次看到XMLHttpRequest在运行。连接的方法被设为GET,然后是URL。最后一个参数,如果是true,即表明请求是非同步的,即是Ajax应用。如果是false,代码将等待服务器,直到得到返回。通过设定最后的参数为true,用户依然可以使用form,甚至调用其它的JavaScript代码,此时服务器在后台处理请求。

xmlHttp的onreadystatechange属性允许你告诉服务器在处理完请求后该做什么,这时可能已经过了五分钟或者五小时。在上面的例子中,当服务器处理完请求,将调用函数updatePage()。

最后调用send(),因为你已经添加了数据(city和state)到URL,你不需要在请求中传输其他数据,因此参数为null。于是一个请求被发送了。

多么的简单和直接!如此,你将集中注意力在程序和界面而不是复杂
request/response。

Listing5的代码很简单。纯粹的文本,作为URL.GET的一部分,而非复杂的POST。不添加XML或content header,请求本身也没有数据。这简直是Ajax的世外桃源(Utopia)。

不要害怕,程序会越来越复杂的。你将学习如何传输POST请求,如何设置头和content types,如何编码XML,如何提高安全性—这张列表会非常长。不必担心,牢牢抓住基本的概念,你将迅速建立起一套Ajax工具库。

处理返回
现在你将处理来自服务器的返回。现在你只要知道两件事:
   在xmlHttp.readyState等于4之前,什么事都不要做
   服务器将把返回信息放在xmlHttp.responseText中
关于ready states,你将在后面学到更多,包括你原本不必了解的。你需要知道xmlHttp.readyState等于4,事情才能继续。使用xmlHttp.responseText,就更简单了。Listing6是演示代码

LISTING6
function updatePage() {
  if (xmlHttp.readyState == 4) {
    var response = xmlHttp.responseText;
    document.getElementById("zipCode").value = response;
  }
}
该函数等待服务器来调用,如果ready state正确,然后使用服务器返回的值,来设置另一个form的字段。结果是zipCode字段突然显示了邮编,而用户没有按任何按钮!这就是我前面提到的桌面程序的感受。

细心的读者可能注意到了,zipCode是普通的文本字段。当服务器返回邮编,updatePage()设置了字段的值为返回的值,用户是可以覆盖这个值的。这样做是出于两个目的:一是让演示代码简单,二是告诉你,有时你想用户能够覆盖服务器的返回值。请记住它们,这有助于设计良好的用户界面(翻译的不好 ——译注)
———————————————————————————————————
关联到Web form
还剩下什么?不多了。你有一段JavaScript代码抓取用户输入的数据,传输给服务器,另一端JavaScript代码监听、处理返回,当返回到来时设置字段的值。如Listing7那样利用JavaScript的优势。

LISTING7
<form>
 <p>City: <input type="text" name="city" id="city" size="25"
       onChange="callServer();" /></p>
 <p>State: <input type="text" name="state" id="state" size="25"
       onChange="callServer();" /></p>
 <p>Zip Code: <input type="text" name="zipCode" id="zipCode" size="5" /></p>
</form>
感觉还有一段常规的代码?没错。当用户在city或state设置新值时,callServer()开始执行,美妙的Ajax就开始运作了。
———————————————————————————————————
结尾
现在,你还没有准备好写Ajax程序,至少还需要看一下Resource中的资料。当然,你已经了解了Ajax的基本知识,运作方式和XMLHttpRequest对象。在接下来的文章中,你将学习如何操作这个对象,如何处理JavaScript和服务器的通信。

现在花点时间来想想Ajax强大的地方。想象Web form不用点击就能被返回。想想非同步是什么意思,想想JavaScript不用等待服务器响应请求。你遇到了哪些问题?你关注哪些领域?你的form设计又将如何改变呢?

如果你花点时间来学习,那么你将比简单的复制粘贴不理解的代码获得更好的服务。所以到目前为止,请充分享受Ajax带来的一切可能。