Ajax 简易教程
这是一个关于 Ajax 的简易教程,希望能消除那些认为 Ajax 令人生畏的人的恐惧。尽管术语的含义是(异步 JavaScript 和 XML),但 Ajax 实际上围绕着一个非常简单的原则。它允许您在不必重新加载页面的情况下操作网页的内容。以下是利用 Ajax 强大功能的关键步骤:
捕获事件(例如,当用户更改编辑字段或按下按钮时)。
事件触发 JavaScript 代码,该代码向 Web 服务器发送查询。
JavaScript 代码从服务器检索结果。
JavaScript 代码使用结果来更改网页的内容。
JavaScript 访问文档对象模型 (DOM) 以更改网页的内容,而无需重新加载网页。例如,假设您的网页包含以下元素:
Total: <input type="text" id="total" />
HTML 标签的 id 部分在 DOM 中创建一个名为 total 的元素,您可以使用以下 JavaScript 代码通过 JavaScript 更改其内容:
document.getElementById('total').value = <some value>;
Web 设计师长期以来一直使用这种功能。Ajax 的真正威力来自于在服务器端而不是在客户端计算总值的能力。为了简单起见,这里有一个示例,它实际上不涉及任何服务器活动,除了返回结果。此示例提供了一个简单的表单,允许您键入邮政编码。当您更改邮政编码字段的值时,JavaScript 代码会在服务器端执行一个 PHP 脚本,该脚本返回到该邮政编码的运费。然后,JavaScript 代码修改 totalshipping 字段以反映服务器响应。
清单 1 中显示的示例页面仅包含 Ajax 页面的最基本元素——主要功能是 getHTTPObject、handleHttpResponse 和 updateShipping。onChange 事件是触发 JavaScript 函数 updateShipping 的原因。您可以改用 onBlur,当您简单地离开邮政编码字段并失去焦点时,它会调用 updateShipping。
getHTTPObject 函数允许您通过 JavaScript 发出页面请求,而 updateShipping 函数执行页面请求。handleHttpResponse 函数接收来自页面请求的输入并提取信息,以便修改页面中的元素(在本例中为 totalshipping 字段)。这些是执行 Ajax 操作所需的三个基本函数。
清单 1. index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Example</title> <script language="javascript" type="text/javascript"> var url = "getShipping.php?zipcode="; function handleHttpResponse() { if (http.readyState == 4) { results = http.responseText; document.getElementById('totalshipping').value = results; } } function updateShipping() { var zipValue = document.getElementById("zip").value; http.open("GET", url + escape(zipValue), true); http.onreadystatechange = handleHttpResponse; http.send(null); } function getHTTPObject() { var xmlhttp; xmlhttp = new XMLHttpRequest(); return xmlhttp; } var http = getHTTPObject(); </script> </head> <body> <form action="post"> <p> ZIP code: <input type="text" size="5" id="zip" onChange="updateShipping();" /> </p> Total Shipping: <input type="text" id="totalshipping" /> </form> </body> </html>
清单 2. getShipping.php
<?php echo "$5.00"; ?>
第一个示例完全避免了 XML。以下代码行将结果作为纯文本抓取:
results = http.responseText;
如果您试用此代码,您会发现当您键入邮政编码(或几乎任何内容,因为代码不进行错误检查)然后离开该字段时,JavaScript 会自动从 PHP 应用程序检索值 $5.00,并将该值放置在“总运费”字段中。
请记住,以上示例尽可能采取了捷径以保持简单。没有任何错误检查或错误处理。甚至没有 HTML 标签名称,只有 id。例如,创建输入字段更常见的方式是 <input type="text" name="totalshipping" id="totalshipping" />。您可能不会将运费放在一个人可以编辑的字段中(尽管您的表单可以在用户单击“购买”时重新验证运费,以纠正任何用户更改)。此外,该示例实际上并未计算运费。以上代码中的 URL 指向一个简单的 PHP 脚本,该脚本返回文本值“$5.00”(清单 2)。一个真正的应用程序会获取邮政编码并使用它来计算运费并返回该值。简而言之,该示例尽可能地简化,以隔离 Ajax 的工作原理,而不是应该如何编写 Ajax 应用程序。
从技术上讲,您可以创建一个完整的 Ajax 应用程序而从不使用 XML,但是您会发现 XML 随着您的 Web 应用程序复杂性的增长而成为虚拟的必需品。以下是如何使用 XML 执行相同的简单网页,再次为了简单起见,尽可能地简化。
请注意在清单 3 中,我们现在使用代码 http.responseXML 抓取响应,并使用代码 xmlDocument.getElementsByTagName('shipping') 提取我们想要的值。另请注意,XML 使用标签 shipping 而不是 totalshipping 来引用总计。这种差异是不必要的,但是本教程的目的在于避免可能的暗示,即 XML 标签名称和 HTML 输入字段 id 必须匹配才能使应用程序工作。它们不必匹配。
清单 3. index-xml.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Example</title> <script language="javascript" type="text/javascript"> var url = "getShippingXML.php?zipcode="; function handleHttpResponse() { if (http.readyState == 4) { var xmlDocument = http.responseXML; var shipping = xmlDocument.getElementsByTagName('shipping') ↪.item(0).firstChild.data; document.getElementById('totalshipping').value = shipping; } } function updateShipping() { var zipValue = document.getElementById("zip").value; http.open("GET", url + escape(zipValue), true); http.onreadystatechange = handleHttpResponse; http.send(null); } function getHTTPObject() { var xmlhttp; xmlhttp = new XMLHttpRequest(); return xmlhttp; } var http = getHTTPObject(); </script> </head> <body> <form action="post"> <p> ZIP code: <input type="text" size="5" name="zip" id="zip" onChange="updateShipping();" /> </p> Total Shipping: <input type="text" id="totalshipping" /> </form> </body> </html>
剩下的唯一事情是修改我们的 PHP 代码以返回 XML 而不是纯文本。请参阅清单 4 以获取 PHP 代码。除了 XML 内容本身之外,请注意代码行,该代码行发送一个标头,在返回 XML 内容本身之前将内容标识为 XML。XML 将运费金额作为 <order> 的子项放置,以及未使用的 <total> 数据。这只是朝着表示页面应返回的更真实的数据集迈出的一小步。
清单 4. GetShippingXML.php
<?php $shipping="$5.00"; $total="$505.00"; $return_value = '<?xml version="1.0" standalone="yes"?> <order> <shipping>'.$shipping.'</shipping> <total>'.$total.'</total> </order>'; header('Content-Type: text/xml'); echo $return_value; ?>
信不信由你,这就是 Ajax 的全部内容。几乎所有其他增加 Ajax 应用程序开发复杂性的因素都属于以下类别。
一个真正的 Ajax 应用程序不会假设 PHP 文件存在。它还会在尝试将其作为参数发送到服务器以查找运费之前检查邮政编码的有效性。(您也可以让服务器验证邮政编码,或者在客户端进行最少的验证,例如确保用户输入了完整的五个数字,然后在服务器端执行邮政编码的完整验证。)
以上示例避免了所有错误处理,以便将重点放在 Ajax 工作原理的基本框架上。显然,您需要在实际应用程序中包含输入验证、错误检测和错误处理。
以上示例代码适用于 Firefox,但不能保证它可以在任何其他浏览器中工作。如果您想从头开始编写所有 Ajax 代码,同时考虑到 Firefox、IE 和 Opera 之间的差异,请购买大量布洛芬——您将需要它。幸运的是,存在大量的 Ajax 库,可以为您管理这些差异。我最喜欢的库之一是 Dojo(请参阅“资源”)。
Ajax 依赖于 DOM 来寻址页面中的各种元素。随着您的页面变得越来越复杂,跟踪所有元素、它们的名称和 id 变得越来越困难。Firefox 有一个内置的 DOM 检查器,它非常有用。如果这还不够,您可以安装 Firebug 附加组件到 Firefox。Firebug 不仅为您提供了一种检查 DOM 的方法,它还可以帮助您调试 JavaScript 代码并管理您的级联样式表(有关该附加组件的链接,请参阅“资源”)。图 1 显示了通过 Firebug 查看的 XML 示例页面。[Reuven Lerner 在本月 22 页的“At the Forge”中介绍了 Firebug。]
至于您必须做什么来处理服务器端的服务,这完全取决于您选择的 Web 应用程序语言和数据库选择,以及其他因素。使用您最擅长的,或者花时间学习您怀疑会减轻编写服务器端代码负担的其他 Web 应用程序语言。
JavaScript 代码优化是一门艺术,但压缩 JavaScript 代码始终有所帮助。例如,缩进所有代码以提高可读性,但是当您完成时,制表符和空格只是用户必须下载的更多字节。您可以使用许多 JavaScript 压缩器之一将 JavaScript 压缩为更少的字节。Dojo 库已为您压缩,并且 Dojo 提供了一个压缩器,您可以在自己的代码上使用。您甚至可以通过 Dojo Shrinksafe 在线压缩您的代码(请参阅“资源”)。
最后,密切关注您在服务器端管理的内容以及在客户端管理的内容。根据您的 Ajax Web 应用程序的功能,您可能会通过将某些信息存储在 cookie 中来获得一些性能提升,或者您可以通过将信息存储在服务器端来加快性能。使用常识并在这两种方法之间进行实验,以查看哪种方法效果最佳。
构建一个出色的 Ajax 应用程序并非总是容易的,但是希望这个关于 Ajax 工作原理的简单教程能够鼓励您尝试一下。现在拿起一个工具包开始吧!
资源
Dojo: dojotoolkit.org
Dojo JavaScript 压缩器: dojotoolkit.org/docs/compressor_system.html
Dojo Shrinksafe: alex.dojotoolkit.org/shrinksafe
Nicholas Petreley 是 Linux Journal 的主编,曾是一名程序员、教师、分析师和顾问,从事 Linux 工作和撰写 Linux 相关文章已有十多年。