处理服务器响应
发送请求,用户高兴地使用 Web 表单(同时服务器在处理请求),而现在服务器完成了请求处理。服务器查看 onreadystatechange
属性确定要调用的方法。除此以外,可以将您的应用程序看作其他应用程序一样,无论是否异步。换句话说,不一定要采取特殊的动作编写响应服务器的方法,只需要改变表单,让用户访问另一个 URL 或者做响应服务器需要的任何事情。这一节我们重点讨论对服务器的响应和一种典型的动作 —— 即时改变用户看到的表单中的一部分。
回调和 Ajax
现在我们已经看到如何告诉服务器完成后应该做什么:将 XMLHttpRequest
对象的 onreadystatechange
属性设置为要运行的函数名。这样,当服务器处理完请求后就会自动调用该函数。也不需要担心该函数的任何参数。我们从一个简单的方法开始,如 清单 12 所示。
清单 12. 回调方法的代码<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
function updatePage() {
alert("Server is done!");
}
</script>
它仅仅发出一些简单的警告,告诉您服务器什么时候完成了任务。在自己的网页中试验这些代码,然后在浏览器中打开(如果希望查看该例中的 XHTML,请参阅 清单 8)。输入电话号码然后离开该字段,将看到一个弹出的警告窗口(如 图 3 所示),但是点击 OK 又出现了……
图 3. 弹出警告的 Ajax 代码
根据浏览器的不同,在表单停止弹出警告之前会看到两次、三次甚至四次警告。这是怎么回事呢?原来我们还没有考虑 HTTP 就绪状态,这是请求/响应循环中的一个重要部分。
HTTP 就绪状态
前面提到,服务器在完成请求之后会在 XMLHttpRequest
的 onreadystatechange
属性中查找要调用的方法。这是真的,但还不完整。事实上,每当 HTTP 就绪状态改变时它都会调用该方法。这意味着什么呢?首先必须理解 HTTP 就绪状态。
HTTP 就绪状态表示请求的状态或情形。它用于确定该请求是否已经开始、是否得到了响应或者请求/响应模型是否已经完成。它还可以帮助确定读取服务器提供的响应文本或数据是否安全。在 Ajax 应用程序中需要了解五种就绪状态:
- 0:请求没有发出(在调用
open()
之前)。
- 1:请求已经建立但还没有发出(调用
send()
之前)。
- 2:请求已经发出正在处理之中(这里通常可以从响应得到内容头部)。
- 3:请求已经处理,响应中通常有部分数据可用,但是服务器还没有完成响应。
- 4:响应已完成,可以访问服务器响应并使用它。
与大多数跨浏览器问题一样,这些就绪状态的使用也不尽一致。您也许期望任务就绪状态从 0 到 1、2、3 再到 4,但实际上很少是这种情况。一些浏览器从不报告 0 或 1 而直接从 2 开始,然后是 3 和 4。其他浏览器则报告所有的状态。还有一些则多次报告就绪状态 1。在上一节中看到,服务器多次调用 updatePage()
,每次调用都会弹出警告框 —— 可能和预期的不同!
对于 Ajax 编程,需要直接处理的惟一状态就是就绪状态 4,它表示服务器响应已经完成,可以安全地使用响应数据了。基于此,回调方法中的第一行应该如 清单 13 所示。
清单 13. 检查就绪状态 function updatePage() {
if (request.readyState == 4)
alert("Server is done!");
}
修改后就可以保证服务器的处理已经完成。尝试运行新版本的 Ajax 代码,现在就会看到与预期的一样,只显示一次警告信息了。
HTTP 状态码
虽然 清单 13 中的代码看起来似乎不错,但是还有一个问题 —— 如果服务器响应请求并完成了处理但是报告了一个错误怎么办?要知道,服务器端代码应该明白它是由 Ajax、JSP、普通 HTML 表单或其他类型的代码调用的,但只能使用传统的 Web 专用方法报告信息。而在 Web 世界中,HTTP 代码可以处理请求中可能发生的各种问题。
比方说,您肯定遇到过输入了错误的 URL 请求而得到 404 错误码的情形,它表示该页面不存在。这仅仅是 HTTP 请求能够收到的众多错误码中的一种(完整的状态码列表请参阅 参考资料 中的链接)。表示所访问数据受到保护或者禁止访问的 403 和 401 也很常见。无论哪种情况,这些错误码都是从完成的响应 得到的。换句话说,服务器履行了请求(即 HTTP 就绪状态是 4)但是没有返回客户机预期的数据。
因此除了就绪状态外,还需要检查 HTTP 状态。我们期望的状态码是 200,它表示一切顺利。如果就绪状态是 4 而且状态码是 200,就可以处理服务器的数据了,而且这些数据应该就是要求的数据(而不是错误或者其他有问题的信息)。因此还要在回调方法中增加状态检查,如 清单 14 所示。
清单 14. 检查 HTTP 状态码 function updatePage() {
if (request.readyState == 4)
if (request.status == 200)
alert("Server is done!");
}
为了增加更健壮的错误处理并尽量避免过于复杂,可以增加一两个状态码检查,请看一看 清单 15 中修改后的 updatePage()
版本。
清单 15. 增加一点错误检查 function updatePage() {
if (request.readyState == 4)
if (request.status == 200)
alert("Server is done!");
else if (request.status == 404)
alert("Request URL does not exist");
else
alert("Error: status code is " + request.status);
}
现在将 getCustomerInfo()
中的 URL 改为不存在的 URL 看看会发生什么。应该会看到警告信息说明要求的 URL 不存在 —— 好极了!很难处理所有的错误条件,但是这一小小的改变能够涵盖典型 Web 应用程序中 80% 的问题。
读取响应文本
现在可以确保请求已经处理完成(通过就绪状态),服务器给出了正常的响应(通过状态码),最后我们可以处理服务器返回的数据了。返回的数据保存在 XMLHttpRequest
对象的 responseText
属性中。
关于 responseText
中的文本内容,比如格式和长度,有意保持含糊。这样服务器就可以将文本设置成任何内容。比方说,一种脚本可能返回逗号分隔的值,另一种则使用管道符(即 |
字符)分隔的值,还有一种则返回长文本字符串。何去何从由服务器决定。
在本文使用的例子中,服务器返回客户的上一个订单和客户地址,中间用管道符分开。然后使用订单和地址设置表单中的元素值,清单 16 给出了更新显示内容的代码。
清单 16. 处理服务器响应 function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/\n/g, "");
} else
alert("status is " + request.status);
}
}
首先,得到 responseText
并使用 JavaScript split()
方法从管道符分开。得到的数组放到 response
中。数组中的第一个值 —— 上一个订单 —— 用 response[0]
访问,被设置为 ID 为 “order” 的字段的值。第二个值 response[1]
,即客户地址,则需要更多一点处理。因为地址中的行用一般的行分隔符(“\n”字符)分隔,代码中需要用 XHTML 风格的行分隔符 <br />
来代替。替换过程使用 replace()
函数和正则表达式完成。最后,修改后的文本作为 HTML 表单 div
中的内部 HTML。结果就是表单突然用客户信息更新了,如图 4 所示。
图 4. 收到客户数据后的 Break Neck 表单
结束本文之前,我还要介绍 XMLHttpRequest
的另一个重要属性 responseXML
。如果服务器选择使用 XML 响应则该属性包含(也许您已经猜到)XML 响应。处理 XML 响应和处理普通文本有很大不同,涉及到解析、文档对象模型(DOM)和其他一些问题。后面的文章中将进一步介绍 XML。但是因为 responseXML
通常和 responseText
一起讨论,这里有必要提一提。对于很多简单的 Ajax 应用程序 responseText
就够了,但是您很快就会看到通过 Ajax 应用程序也能很好地处理 XML。
结束语
您可能对 XMLHttpRequest
感到有点厌倦了,我很少看到一整篇文章讨论一个对象,特别是这种简单的对象。但是您将在使用 Ajax 编写的每个页面和应用程序中反复使用该对象。坦白地说,关于 XMLHttpRequest
还真有一些可说的内容。下一期文章中将介绍如何在请求中使用 POST
及 GET
,来设置请求中的内容头部和从服务器响应读取内容头部,理解如何在请求/响应模型中编码请求和处理 XML。
再往后我们将介绍常见 Ajax 工具箱。这些工具箱实际上隐藏了本文所述的很多细节,使得 Ajax 编程更容易。您也许会想,既然有这么多工具箱为何还要对底层的细节编码。答案是,如果不知道应用程序在做什么,就很难发现应用程序中的问题。
因此不要忽略这些细节或者简单地浏览一下,如果便捷华丽的工具箱出现了错误,您就不必挠头或者发送邮件请求支持了。如果了解如何直接使用 XMLHttpRequest
,就会发现很容易调试和解决最奇怪的问题。只有让其解决您的问题,工具箱才是好东西。
因此请熟悉 XMLHttpRequest
吧。事实上,如果您有使用工具箱的 Ajax 代码,可以尝试使用 XMLHttpRequest
对象及其属性和方法重新改写。这是一种不错的练习,可以帮助您更好地理解其中的原理。
下一期文章中将进一步讨论该对象,探讨它的一些更有趣的属性(如 responseXML
),以及如何使用 POST
请求和以不同的格式发送数据。请开始编写代码吧,一个月后我们再继续讨论。
分享到:
相关推荐
AJAX响应信息是AJAX通讯中的一个重要的部分。理解如何处理响应信息,特别是在使用新的交互操作形式的时候,这一点非常重要的。本文解释了AJAX请求-响应过程的本质,并分析了如何处理AJAX响应信息。
responseText/responseXML :服务器的响应字符串 status:服务器返回的HTTP状态码 statusText: 服务器返回的HTTP状态信息 readyState :对象状态(0-4) 0 = 未初始化 1 = 正在加载 2 = 已加载 3 = 交互...
提高AJAX客户端响应速度,AJAX技术,编程技巧
本卷从最易于理解和使用的那部分入手,介绍ASP.NET AJAX框架中能够与传统ASP.NET无缝对接的服务器端部分,包括服务器端ASP.NET AJAX Extensions与ASP.NET AJAX Control Toolkit。这部分内容不需要读者有任何的客户端...
ajax 跨域调用的服务器端解决办法,很实用,附带源码
数据是使用AJAX向易语言程序请求交互取到的。虽然wke浏览器也可以交互数据,但个人感觉还是Ajax顺手。像做Web应用系统一样做易语言程序,是一种什么样的feel?。用html写窗口UI,然后用Ajax交互数据。把web应用搬到...
包含了ajax上传附件到服务器的前后台代码
java服务器端处理: SessionValidateFilter中修改: if (ServerInfo.isAjax(request)) { request.setAttribute("statusCode", 301); request.setAttribute("message", "Session timeout!"); response....
AJAX 服务器端控件详解 针对ASP.NET 2.0以上版本,VS 增加了AJAX有务器端控件
Ajax提交数据更新服务器内容
Ajax 设置事件处理程序
Ajax Control Toolkit 34个服务器端控件
json2 ajax返回list处理 在jsp页面 遍历
ajax.dll 配置 ajax局部无刷新 ajax 异步处理
全面理解 HTTP 状态代码、就绪状态和 XMLHttpRequest 对象
使用 JavaScript 向服务器提出请求并处理响应而不阻塞用户核心对象XMLHttpRequest。通过这个对象,您的 JavaScript 可在不重载页面的情况与 Web 服务器交换数据,即在不需要刷新页面的情况下,就可以产生局部刷新的...
掌握 Ajax第 1 部分-Ajax 简介 掌握 Ajax第 2 部分-使用 JavaScript 和 Ajax 发出异步请求 掌握 Ajax第 3 部分-Ajax 中的高级请求和响应 掌握 Ajax第 4 部分-利用 DOM 进行 Web...掌握 Ajax第 11 部分--服务器端的 JSON
AJAX的工作原理相当与在用户和服务器之间加了一个中间层,使用户请求与服务器响应异步化。这样还可以把以前的一些服务器负担的工作转交给客户端,利用客户端闲置的处理能力来处理,减轻服务器和宽带的负担。 AJAX是...
使用 jquery ajax访问后台服务器demo
Ajax工作原理是提供与服务器异步通信的能力,从而使用户从请求/响应的循环中解脱出来。借助于Ajax,可以在用户单击按钮时,使用JavaScript和DHTML立即更新UI,并向服务器发出异步请求,以执行更新或查询数据库。当...