Ajax 完整教程 9

清单 6. 忽略状态代码的回调函数

   function updatePage() {
     if (request.readyState == 4) {
       var response = request.responseText.split("|");
       document.getElementById("order").value = response[0];
       document.getElementById("address").innerHTML =
         response[1].replace(/\n/g, "<br />");
     }
   }
这对于 Ajax 编程来说证明是一种短视而错误的方法。如果脚本需要认证,而请求却没有提供有效的证书,那么服务器就会返回诸如 403 或 401 之类的错误代码。然而,由于服务器对请求进行了应答,因此就绪状态就被设置为 4(即使应答并不是请求所期望的也是如此)。最终,用户没有获得有效数据,当 JavaScript 试图使用不存在的服务器数据时就可能会出现严重的错误。

它花费了最小的努力来确保服务器不但完成了一个请求,而且还返回了一个 “一切良好” 的状态代码。这个代码是 "200",它是通过 XMLHttpRequest 对象的 status 属性来报告的。为了确保服务器不但完成了一个请求,而且还报告了一个 OK 状态,请在您的回调函数中添加另外一个检查功能,如 清单 7 所示。

清单 7. 检查有效状态代码

   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, "<br />");
       } else
         alert("status is " + request.status);
     }
   }
通过添加这几行代码,您就可以确认是否存在问题,用户会看到一个有用的错误消息,而不仅仅是看到一个由断章取义的数据所构成的页面,而没有任何解释。

重定向和重新路由

在深入介绍有关错误的内容之前,我们有必要来讨论一下有关一个在使用 Ajax 时 并不需要 关心的问题 —— 重定向。在 HTTP 状态代码中,这是 300 系列的状态代码,包括:

·301:永久移动
·302:找到(请求被重新定向到另外一个 URL/URI 上)
·305:使用代理(请求必须使用一个代理来访问所请求的资源)

Ajax 程序员可能并不太关心有关重定向的问题,这是由于两方面的原因:

·首先,Ajax 应用程序通常都是为一个特定的服务器端脚本、servlet 或应用程序而编写的。对于那些您看不到就消失了的组件来说,Ajax 程序员就不太清楚了。因此有时您会知道资源已经移动了(因为您移动了它,或者通过某种手段移动了它),接下来要修改请求中的 URL,并且不会再碰到这种结果了。
更为重要的一个原因是:Ajax 应用程序和请求都是封装在沙盒中的。这就意味着提供生成 Ajax 请求的 Web 页面的域必须是对这些请求进行响应的域。因此 ebay.com 所提供的 Web 页面就不能对一个在 amazon.com 上运行的脚本生成一个 Ajax 风格的请求;在 ibm.com 上的 Ajax 应用程序也无法对在 netbeans.org 上运行的 servlets 发出请求。
·结果是您的请求无法重定向到其他服务器上,而不会产生安全性错误。在这些情况中,您根本就不会得到状态代码。通常在调试控制台中都会产生一个 JavaScript 错误。因此,在对状态代码进行充分的考虑之后,您就可以完全忽略重定向代码的问题了。

结果是您的请求无法重定向到其他服务器上,而不会产生安全性错误。在这些情况中,您根本就不会得到状态代码。通常在调试控制台中都会产生一个 JavaScript 错误。因此,在对状态代码进行充分的考虑之后,您就可以完全忽略重定向代码的问题了。

错误

一旦接收到状态代码 200 并且意识到可以很大程度上忽略 300 系列的状态代码之后,所需要担心的唯一一组代码就是 400 系列的代码了,这说明了不同类型的错误。回头再来看一下 清单 7,并注意在对错误进行处理时,只将少数常见的错误消息输出给用户了。尽管这是朝正确方向前进的一步,但是要告诉从事应用程序开发的用户和程序员究竟发生了什么问题,这些消息仍然是没有太大用处的。

首先,我们要添加对找不到的页的支持。实际上这在大部分产品系统中都不应该出现,但是在测试脚本位置发生变化或程序员输入了错误的 URL 时,这种情况并不罕见。如果您可以自然地报告 404 错误,就可以为那些困扰不堪的用户和程序员提供更多帮助。例如,如果服务器上的一个脚本被删除了,我们就可以使用 清单 7 中的代码,这样用户就会看到一个如 图 5 所示的非描述性错误。

边界情况和困难情况

看到现在,一些新手程序员就可能会这究竟是要讨论什么内容。有一点事实大家需要知道:只有不到 5% 的 Ajax 请求需要使用诸如 2、3 之类的就绪状态和诸如 403 之类的状态代码(实际上,这个比率可能更接近于 1% 甚至更少)。这些情况非常重要,称为 边界情况(edge case) —— 它们只会在一些非常特殊的情况下发生,其中遇到的都是最奇特的问题。虽然这些情况并不普遍,但是这些边界情况却占据了大部分用户所碰到的问题的 80%!

对于典型的用户来说,应用程序 100 次都是正常工作的这个事实通常都会被忘记,然而应用程序只要一次出错就会被他们清楚地记住。如果您可以很好地处理边界情况(或困难情况),就可以为再次访问站点的用户提供满意的回报。

图 5. 常见错误处理

用户无法判断问题究竟是认证问题、没找到脚本(此处就是这种情况)、用户错误还是代码中有些地方产生了问题。添加一些简单的代码可以让这个错误更加具体。请参照 清单 8,它负责处理没找到的脚本或认证发生错误的情况,在出现这些错误时都会给出具体的消息。

清单 8. 检查有效状态代码

   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, "<br />");
       } else if (request.status == 404) {
         alert ("Requested URL is not found.");
       } else if (request.status == 403) {
         alert("Access denied.");
       } else
         alert("status is " + request.status);
     }
   }
虽然这依然相当简单,但是它的确多提供了一些有用的信息。图 6 给出了与 图 5 相同的错误,但是这一次错误处理代码向用户或程序员更好地说明了究竟发生了什么。

图 6. 特殊错误处理

在我们自己的应用程序中,可以考虑在发生认证失败的情况时清除用户名和密码,并向屏幕上添加一条错误消息。我们可以使用类似的方法来更好地处理找不到脚本或其他 400 类型的错误(例如 405 表示不允许使用诸如发送 HEAD 请求之类不可接受的请求方法,而 407 则表示需要进行代理认证)。然而不管采用哪种选择,都需要从对服务器上返回的状态代码开始入手进行处理。

其他请求类型

如果您真希望控制 XMLHttpRequest 对象,可以考虑最后实现这种功能 —— 将 HEAD 请求添加到指令中。在前两篇文章中,我们已经介绍了如何生成 GET 请求;在马上就要发表的一篇文章中,您会学习有关使用 POST 请求将数据发送到服务器上的知识。不过本着增强错误处理和信息搜集的精神,您应该学习如何生成 HEAD 请求。

生成请求

实际上生成 HEAD 请求非常简单;您可以使用 "HEAD"(而不是 "GET" 或 "POST")作为第一个参数来调用 open() 方法,如 清单 9 所示。


[本日志由 hesper 于 2007-05-27 10:29 AM 编辑]
文章来自: 转贴
引用通告地址: http://www.wantfly.cn/trackback.asp?tbID=237
Tags: Ajax
评论: 0 | 引用: 0 | 查看次数: 3163
发表评论
昵 称:
密 码: 游客发言不需要密码.
验证码:
内 容:
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 关闭 | [img]标签 关闭