但是QAjax ?i>仅仅 是一U时,它是一U构建网站的强大Ҏ(gu)Q而且不像学习一U全新的语言那样困难?/p>
但在详细探讨 Ajax 是什么之前,先让我们花几分钟了解 Ajax ?/i> 什么。目前,~写应用E序时有两种基本的选择Q?/p>
两者是cM的,桌面应用E序通常?CD Z质(有时候可从网站下载)q完全安装到(zhn)的计算Z。桌面应用程序可能用互联网下蝲?斎ͼ但运行这些应用程序的代码在桌面计机上。Web 应用E序q行在某处的 Web 服务器上 —?毫不奇怪,要通过 Web 览器访问这U应 用程序?/p>
不过Q比q些应用E序的运行代码放在何处更重要的是Q应用程序如何运转以及如何与其进行交互。桌面应用程序一般很快(在(zhn)的计算 Zq行Q不用等待互联网q接Q,h漂亮的用L面(通常和操作系l有养I和非凡的动态性。可以单凅R选择、输入、打开菜单和子?单、到处E游,基本上不需要等待?/p>
另一斚wQWeb 应用E序是最新的潮流Q它们提供了在桌面上不能实现的服务(比如 Amazon.com ?eBayQ。但是,伴随着 Web 的强大?出现的是{待Q等待服务器响应Q等待屏q刷斎ͼ{待hq回和生成新的页面?/p>
昄q样说过于简略了Q但基本的概念就是如此。?zhn)可能已经猜到QAjax 试建立桌面应用E序的功能和交互性,与不断更新的 Web 应用 E序之间的桥梁。可以用像桌面应用E序中常见的动态用L面和漂亮的控Ӟ不过是在 Web 应用E序中?/p>
q等什么呢Q我们来看看 Ajax 如何笨拙的 Web 界面转化成能q速响应的 Ajax 应用E序吧?/p>
在谈?Ajax Ӟ实际上涉及到多种技术,要灵zdq用它必L入了解这些不同的技术(本系列的头几文章将分别讨论q些技术)。好 消息是?zhn)可能已经非常熟(zhn)其中的大部分技术,更好的是q些技术都很容易学习,q不像完整的~程语言Q如 Java ?RubyQ那样困难?/p>
![]() |
|
下面?Ajax 应用E序所用到的基本技术:
div
?code>span 和其他动?HTML 元素来标?HTML?
我们来进一步分析这些技术的职责。以后的文章中我深入讨些技术,目前只要熟?zhn)q些lg和技术就可以了。对q些代码熟(zhn),?容易从对这些技术的零散了解转变到真正把握这些技术(同时也真正打开?Web 应用E序开发的大门Q?/p>
要了解的一个对象可能对(zhn)来说也是最陌生的,?XMLHttpRequest
。这是一?JavaScript 对象Q创对象很简单,?a >清单 1 所C?/p>
|
下一期文章中进一步讨个对象,现在要知道这是处理所有服务器通信的对象。l阅M前,先停下来想一惻I通过 XMLHttpRequest
对象与服务器q行对话的是 JavaScript 技术。这不是一般的应用E序,q恰恰是 Ajax 的强大功?的来源?/p>
在一般的 Web 应用E序中,用户填写表单字段q单?Submit 按钮。然后整个表单发送到服务器,服务器将它{发给处理表单的脚 本(通常?PHP ?JavaQ也可能?CGI q程或者类似的东西Q,脚本执行完成后再发送回全新的页面。该面可能是带有已l填充某些数?的新表单?HTMLQ也可能是确认页面,或者是hҎ(gu)原来表单中输入数据选择的某些选项的页面。当Ӟ在服务器上的脚本或程序处理和q?回新表单时用户必ȝ待。屏q变成一片空白,{到服务器返回数据后再重新绘制。这是交互性差的原因,用户得不到立卛_馈,因此感觉 不同于桌面应用程序?/p>
Ajax 基本上就是把 JavaScript 技术和 XMLHttpRequest
对象攑֜ Web 表单和服务器之间。当用户填写表单Ӟ?据发送给一?JavaScript 代码?i>不是 直接发送给服务器。相反,JavaScript 代码捕获表单数据q向服务器发送请求。同时用户屏q?上的表单也不会闪烁、消失或延迟。换句话_JavaScript 代码在幕后发送请求,用户甚至不知道请求的发出。更好的是,h是异步发送的 Q就是说 JavaScript 代码Q和用户Q不用等待服务器的响应。因此用户可以l输入数据、滚动屏q和使用应用E序?/p>
然后Q服务器数据返?JavaScript 代码Q仍然在 Web 表单中)Q后者决定如何处理这些数据。它可以q速更新表单数据,让h感觉?用程序是立即完成的,表单没有提交或刷新而用户得C新数据。JavaScript 代码甚至可以Ҏ(gu)到的数据执行某种计算Q再发送另一个请求, 完全不需要用户干预!q就?XMLHttpRequest
的强大之处。它可以Ҏ(gu)需要自行与服务器进行交互,用户甚至可以完全不知?q后发生的一切。结果就是类g桌面应用E序的动态、快速响应、高交互性的体验Q但是背后又拥有互联|的全部强大力量?/p>
得到 XMLHttpRequest
的句柄后Q其他的 JavaScript 代码非常简单了。事实上Q我们将使用 JavaScript 代码完成非常 基本的Q务:
对于前两点,需要非常熟(zhn)?getElementById()
Ҏ(gu)Q如 清单 2 所C?/p>
清单 2. ?JavaScript 代码捕获和设|字D?/font>
|
q里没有特别需要注意的地方Q真是好极了Q?zhn)应该认识到这里ƈ没有非常复杂的东ѝ只要掌握了 XMLHttpRequest
QAjax 应用E序的其他部分就是如 清单 2 所C的?JavaScript 代码了,混合有少量的 HTML。同Ӟq要用一点儿 DOM Q我们就来看看吧?/p>
最后还?DOMQ即文档对象模型。可能对有些读者来?DOM 有点儿o人生畏,HTML 设计者很用它Q即?JavaScript E序员也不大?到它Q除非要完成某项高端~程d。大量?DOM ?i>?/i> 复杂?Java ?C/C++ E序Q这可能是 DOM 被认为难以学习的原因?
q运的是Q在 JavaScript 技术中使用 DOM 很容易,也非常直观。现在,按照常规也许应该说明如何使用 DOMQ或者至要l出一些示?代码Q但q样做也可能误导(zhn)。即使不理会 DOMQ仍然能深入地探?AjaxQ这也是我准备采用的Ҏ(gu)。以后的文章再ơ讨?DOMQ现在只?知道可能需?DOM 可以了。当需要在 JavaScript 代码和服务器之间传?XML 和改?HTML 表单的时候,我们再深入研I?DOM。没有它?能做一些有的工作Q因此现在就?DOM 攑ֈ一边吧?/p>
![]() ![]() |
![]()
|
有了上面的基知识后,我们来看看一些具体的例子?code>XMLHttpRequest ?Ajax 应用E序的核心,而且对很多读者来说可?q比较陌生,我们׃q里开始吧。从 清单 1 可以看出Q创建和使用q个对象非常单,不是吗?{一{?/p>
q记得几q前的那些讨厌的览器战争吗Q没有一样东西在不同的浏览器上得到同Ll果。不?zhn)是否怿Q这些战争仍然在l箋Q虽?规模较小。但令h奇怪的是,XMLHttpRequest
成了q场战争的牺牲品之一。因此获?XMLHttpRequest
对象可能 需要采用不同的Ҏ(gu)。下面我详l地q行解释?/p>
Microsoft 览?Internet Explorer 使用 MSXML 解析器处?XMLQ可以通过 参考资?/font> q一步了?MSXML Q。因此如果编写的 Ajax 应用E序要和 Internet Explorer 打交道,那么必须用一U特D的方式创徏对象?/p>
但ƈ不是q么单。根?Internet Explorer 中安装的 JavaScript 技术版本不同,MSXML 实际上有两种不同的版本,因此必须对这两种 情况分别~写代码。请参阅 清单 3Q其中的代码?Microsoft 览器上创徏了一?XMLHttpRequest
?
清单 3. ?Microsoft 览器上创徏 XMLHttpRequest 对象
|
(zhn)对q些代码可能q不完全理解Q但没有关系。当本系列文章结束的时候,(zhn)将?JavaScript ~程、错误处理、条件编译等有更q了解 。现在只要牢牢记住其中的两行代码Q?/p>
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
?/p>
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
?/p>
q两行代码基本上是试使用一个版本的 MSXML 创徏对象Q如果失败则使用另一个版本创对象。不错吧Q如果都不成功,则将 xmlHttp
变量设ؓ falseQ告诉?zhn)的代码出C问题。如果出现这U情况,可能是因为安装了?Microsoft 览器,需要?不同的代码?/p>
处理 Mozilla 和非 Microsoft 览?/font>
如果选择的浏览器不是 Internet ExplorerQ或者ؓ?Microsoft 览器编写代码,需要用不同的代码。事实上是 清单 1 所C的一行简单代码:
var xmlHttp = new XMLHttpRequest object;
?/p>
q行单得多的代码?Mozilla、Firefox、Safari、Opera 以及基本上所有以M形式或方式支?Ajax 的非 Microsoft 览器中Q创??XMLHttpRequest
对象?/p>
关键是要支持所?/i> 览器。谁愿意~写一个只能用?Internet Explorer 或者非 Microsoft 览器的应用E序呢?或者更p,?~写一个应用程序两ơ?当然不!因此代码要同时支?Internet Explorer 和非 Microsoft 览器?a >清单 4 昄?q样的代码?/p>
清单 4. 以支持多U浏览器的方式创?XMLHttpRequest 对象
|
现在先不那些注释掉的奇怪符P?@cc_on
Q这是特D的 JavaScript ~译器命令,在下一期针?XMLHttpRequest
的文章中详细讨论。这D代码的核心分ؓ三步Q?/p>
xmlHttp
来引用即创建的 XMLHttpRequest
对象?
Msxml2.XMLHTTP
对象创徏它?
Microsoft.XMLHTTP
对象?xmlHttp
Q则以非 Microsoft 的方式创对象?最后,xmlHttp
应该引用一个有效的 XMLHttpRequest
对象Q无行什么样的浏览器?/p>
安全性如何呢Q现在浏览器允许用户提高他们的安全等U,关闭 JavaScript 技术,用览器中的Q何选项。在q种情况下,代码无论?何都不会工作。此时必适当地处理问题,q需要单独的一文章来讨论Q要攑ֈ以后了(q个pd够长了吧Q不用担心,d之前也许(zhn)就 掌握了)。现在要~写一D健壮但不够完美的代码,对于掌握 Ajax 来说很好了。以后我们还讨论更多的l节?/p>
![]() ![]() |
![]()
|
现在我们介绍?AjaxQ对 XMLHttpRequest
对象以及如何创徏它也有了基本的了解。如果阅d很仔l,(zhn)可能已l知道与 服务器上?Web 应用E序打交道的?JavaScript 技术,而不是直接提交给那个应用E序?HTML 表单?/p>
q缺什么呢Q到底如何?XMLHttpRequest
。因D代码非帔R要,(zhn)编写的每个 Ajax 应用E序都要以某U?形式使用它,先看?Ajax 的基本请?响应模型是什么样吧?/p>
(zhn)已l有了一个崭新的 XMLHttpRequest
对象Q现在让它干Ҏ(gu)儿吧。首先需要一?Web 面能够调用?JavaScript Ҏ(gu) Q比如当用户输入文本或者从菜单中选择一Ҏ(gu)Q。接下来是在所?Ajax 应用E序中基本都雷同的流E:
清单 5 中的CZ Ajax Ҏ(gu)是按照q个序l织的:
|
其中大部分代码意义都很明。开始的代码使用基本 JavaScript 代码获取几个表单字段的倹{然后设|一?PHP 脚本作ؓ链接的目标?要注意脚?URL 的指定方式,city ?stateQ来自表单)使用单的 GET 参数附加?URL 之后?/p>
然后打开一个连接,q是(zhn)第一ơ看C?XMLHttpRequest
。其中指定了q接Ҏ(gu)QGETQ和要连接的 URL。最后一个参?如果设ؓ true
Q那么将h一个异步连接(q就?Ajax 的由来)。如果?false
Q那么代码发求后等 待服务器q回的响应。如果设?true
Q当服务器在后台处理h的时候用户仍然可以用表单(甚至调用其他 JavaScript ?法)?/p>
xmlHttp
Q要CQ这?XMLHttpRequest
对象实例Q的 onreadystatechange
属性可以告诉服 务器在运?i>完成 后(可能要用五分钟或者五个小Ӟ做什么。因Z码没有等待服务器Q必让服务器知道怎么做以便?zhn)能作出响?。在q个CZ中,如果服务器处理完了请求,一个特D的名ؓ updatePage()
的方法将被触发?/p>
最后,使用?null
调用 send()
。因为已l在h URL 中添加了要发送给服务器的数据Qcity ?stateQ?Q所以请求中不需要发送Q何数据。这样就发出了请求,服务器按照?zhn)的要求工作?/p>
如果没有发现M新鲜的东西,(zhn)应该体会到q是多么单明了!除了牢牢C Ajax 的异步特性外Q这些内定w相当单。应该感Ȁ Ajax 使?zhn)能够专心~写漂亮的应用程序和界面Q而不用担心复杂的 HTTP h/响应代码?/p>
清单 5 中的代码说明?Ajax 的易用性。数据是单的文本Q可以作?URL 的一部分。用 GET 而不是更复杂 ?POST 发送请求。没?XML 和要d的内容头部,h体中没有要发送的数据Q换句话_q就?Ajax 的乌托邦?/p>
不用担心Q随着本系列文章的展开Q事情会变得来复杂。?zhn)看到如何发?POST h、如何设|请求头部和内容cd、如何在消息?~码 XML、如何增加请求的安全性,可以做的工作q有很多Q暂时先不用那些难点,掌握好基本的东西p了,很快我们׃建立一整套?Ajax 工具库?/p>
现在要面Ҏ(gu)务器的响应了。现在只要知道两点:
xmlHttp.readyState
属性的值等?4?
xmlHttp.responseText
属性中?其中的第一点,卛_l状态,在下一文章中详细讨论Q?zhn)进一步了?HTTP h的阶D,可能比?zhn)设想的还多。现在只要检查一个特 定的|4Q就可以了(下一期文章中q有更多的D介绍Q。第二点Q?xmlHttp.responseText
属性获得服务器的响应, q很单?a >清单 6 中的CZҎ(gu)可供服务器根?清单 5 中发送的数据调用?/p>
|
q些代码同样既不难也不复杂。它{待服务器调用,如果是就l状态,则用服务器q回的|q里是用戯入的城市和州?ZIP ~码Q?讄另一个表单字D늚倹{于是包?ZIP ~码?zipCode
字段H然出现了,而用?i>没有按Q何按?/i>Q这是前面所?的桌面应用程序的感觉。快速响应、动态感受等{,q些都只因ؓ有了小的一D?Ajax 代码?/p>
l心的读者可能注意到 zipCode
是一个普通的文本字段。一旦服务器q回 ZIP ~码Q?code>updatePage() Ҏ(gu)?用城?州的 ZIP ~码讄那个字段的|用户可以改写该倹{这样做有两个原因:保持例子单,说明有时候可?i>希望 用户能够 修改服务器返回的数据。要Cq两点,它们对于好的用户界面设计来说很重要?/p>
![]() ![]() |
![]()
|
q有什么呢Q实际上没有多少了。一?JavaScript Ҏ(gu)捕捉用户输入表单的信息ƈ其发送到服务器,另一?JavaScript Ҏ(gu)监听和处 理响应,q在响应q回时设|字D늚倹{所有这些实际上都依赖于调用 W一?JavaScript Ҏ(gu)Q它启动了整个过E。最明显的办?是在 HTML 表单中增加一个按钮,但这?2001 q的办法Q?zhn)不这栯为吗Q还是像 清单 7 q样利用 JavaScript 技 术吧?/p>
|
如果感觉q像是一D늛当普通的代码Q那对了,正是如此Q当用户?city ?state 字段中输入新的值时Q?code>callServer() Ҏ(gu)p触发Q于?Ajax 开始运行了。有点儿明白怎么回事了吧Q好Q就是如此!
![]() ![]() |
![]()
|
现在(zhn)可能已l准备开始编写第一?Ajax 应用E序了,臛_也希望认真读一?参考资?/font> 中的那些文章了吧 Q但可以首先从这些应用程序如何工作的基本概念开始,?XMLHttpRequest
对象有基本的了解。在下一期文章中Q?zhn)掌握?个对象,学会如何处理 JavaScript 和服务器的通信、如何?HTML 表单以及如何获得 DOM 句柄?/p>
现在先花点儿旉考虑考虑 Ajax 应用E序有多么强大。设想一下,当单L钮、输入一个字Dc从l合框中选择一个选项或者用鼠标在屏 q上拖动ӞWeb 表单能够立刻作出响应会是什么情形。想一?i>异步 I竟意味着什么,想一?JavaScript 代码q行而且不等?服务器对它的h作出响应。会遇到什么样的问题?会进入什么样的领域?考虑到这U新的方法,~程的时候应如何改变表单的设计?
如果在这些问题上׃点儿旉Q与单地剪切/_脓(chung)某些代码到?zhn)?gu)不理解的应用E序中相比,收益会更多。在下一期文章中Q我们将 把这些概念付诸实践,详细介绍使应用程序按照这U方式工作所需要的代码。因此,现在先n受一?Ajax 所带来的可能性吧?/p>