Ajax学习(三)

来源:互联网 发布:eagle mac下载 编辑:程序博客网 时间:2024/05/17 07:15

HTTP 就绪状态
HTTP 状态代码
可以生成的请求类型

深入了解 HTTP 就绪状态

XMLHttpRequest 对象有一个名为 readyState 的属性。这个属性确保服务器已经完成了一个请求,通常会使用一个回调函数从服务器中读出数据来更新 Web 表单或页面的内容。

Microsoft™ 和 Internet Explorer 使用了一个名为 XMLHttp 的对象,而不是 XMLHttpRequest 对象,而 Mozilla、Opera、Safari 和 大部分非 Microsoft 浏览器都使用的是后者。为了简单性起见,我将这两个对象都简单地称为 XMLHttpRequest。这既符合我们在 Web 上看到的情况,又符合 Microsoft 在 Internet Explorer 7.0 中使用 XMLHttpRequest 作为请求对象的意图。

隐秘就绪状态

第一种就绪状态的特点是 readyState 属性为 0(readyState == 0),表示未初始化状态。一旦对请求对象调用 open() 之后,这个属性就被设置为 1。由于您通常都是在一对请求进行初始化之后就立即调用 open(),因此很少会看到 readyState == 0 的状态。另外,未初始化的就绪状态在实际的应用程序中是没有真正的用处的。也许,您可能会在生成新请求之前希望确保请求对象是处于未初始化状态(readyState == 0)。这实际上是要确保另外一个函数没有同时使用这个对象。

每一次的状态改变既readyState的值的改变,都会调用XmlHttpRequest对象onreadystatechange属性后面对应的方法。

当 0 等于 4 时
在多个 JavaScript 函数都使用相同的请求对象时,您需要检查就绪状态 0 来确保这个请求对象没有正在使用,这种机制会产生问题。由于 readyState == 4 表示一个已完成的请求,因此您经常会发现那些目前没在使用的处于就绪状态的请求对象仍然被设置成了 4 —— 这是因为从服务器返回来的数据已经使用过了,但是从它们被设置为就绪状态之后就没有进行任何变化。有一个函数 abort() 会重新设置请求对象,但是这个函数却不是真正为了这个目的而使用的。如果您 必须 使用多个函数,最好是为每个函数都创建并使用一个函数,而不是在多个函数之间共享相同的对象。

浏览器的不一致性

在 Firefox 1.5  中看到的就绪状态:1 2 3 4

Safari 2.0.1  中看到的就绪状态:2  3   4

Opera 8.5  中看到的就绪状态:2  3   4

Internet Explorer 会显示如下状态:1   2    3  4

响应数据

responseText 属性,用来从服务器上获取数据。一旦服务器完成对请求的处理之后,就可以将响应请求数据所需要的任何数据放到请求的 responseText 中了。然后回调函数就可以使用这些数据。

在浏览器上测试responseText属性,您会看到就绪状态为 3 的响应在每个脚本、每个服务器甚至每个浏览器上都是不一样的。不过,这在调试应用程序中依然是非常有用的。

获取安全数据

      所有的文档和规范都强调,只有在就绪状态为 4 时数据才可以安全使用。相信我,当就绪状态为 3 时,您很少能找到无法从 responseText 属性获取数据的情况。然而,在应用程序中将自己的逻辑依赖于就绪状态 3 可不是什么好主意 , 一旦您编写了依赖于就绪状态 3 的完整数据的的代码,几乎就要自己来负责当时的数据不完整问题了。
      比较好的做法是向用户提供一些反馈,说明在处于就绪状态 3 时,很快就会有响应了。尽管使用 alert() 之类的函数显然不是什么好主意 —— 使用 Ajax 然后使用一个警告对话框来阻塞用户显然是错误的 —— 不过您可以在就绪状态发生变化时更新表单或页面中的域。例如,对于就绪状态 1 来说要将进度指示器的宽度设置为 25%,对于就绪状态 2 来说要将进度指示器的宽度设置为 50%,对于就绪状态 3 来说要将进度指示器的宽度设置为 75%,当就绪状态为 4 时将进度指示器的宽度设置为 100%(完成)。

HTTP 状态代码

       有了就绪状态和您在 Ajax 编程技术中学习到的服务器的响应,您就可以为 Ajax 应用程序添加另外一级复杂性了 —— 这要使用 HTTP 状态代码。在 Web 浏览器中您可能已经看到过几个状态代码:
·401:未经授权
·403:禁止
·404:没找到

200:一切正常

   如果脚本需要认证,而请求却没有提供有效的证书,那么服务器就会返回诸如 403 或 401 之类的错误代码。然而,由于服务器对请求进行了应答,因此就绪状态就被设置为 4(即使应答并不是请求所期望的也是如此)。最终,用户没有获得有效数据,当 JavaScript 试图使用不存在的服务器数据时就可能会出现严重的错误。

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

重定向和重新路由

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

错误
一旦接收到状态代码 200 并且意识到可以很大程度上忽略 300 系列的状态代码之后,所需要担心的唯一一组代码就是 400 系列的代码了,这说明了不同类型的错误。并注意在对错误进行处理时,只将少数常见的错误消息输出给用户了。尽管这是朝正确方向前进的一步,但是要告诉从事应用程序开发的用户和程序员究竟发生了什么问题,这些消息仍然是没有太大用处的。
首先,我们要添加对找不到的页的支持。实际上这在大部分产品系统中都不应该出现,但是在测试脚本位置发生变化或程序员输入了错误的 URL 时,这种情况并不罕见。如果您可以自然地报告 404 错误,就可以为那些困扰不堪的用户和程序员提供更多帮助。

边界情况和困难情况
看到现在,一些新手程序员就可能会这究竟是要讨论什么内容。有一点事实大家需要知道:只有不到 5% 的 Ajax 请求需要使用诸如 2、3 之类的就绪状态和诸如 403 之类的状态代码(实际上,这个比率可能更接近于 1% 甚至更少)。这些情况非常重要,称为 边界情况(edge case) —— 它们只会在一些非常特殊的情况下发生,其中遇到的都是最奇特的问题。虽然这些情况并不普遍,但是这些边界情况却占据了大部分用户所碰到的问题的 80%!
对于典型的用户来说,应用程序 100 次都是正常工作的这个事实通常都会被忘记,然而应用程序只要一次出错就会被他们清楚地记住。如果您可以很好地处理边界情况(或困难情况),就可以为再次访问站点的用户提供满意的回报。

示例代码:

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 if (request.status == 404) {
         alert ("Requested URL is not found.");
       } else if (request.status == 403) {
         alert("Access denied.");
       } else
         alert("status is " + request.status);
     }
   }

其他请求类型
       如果您真希望控制 XMLHttpRequest 对象,可以考虑最后实现这种功能,将 HEAD 请求添加到指令中。

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

       当您这样生成一个 HEAD 请求时,服务器并不会像对 GET 或 POST 请求一样返回一个真正的响应。相反,服务器只会返回资源的 头(header),这包括响应中内容最后修改的时间、请求资源是否存在和很多其他有用信息。您可以在服务器处理并返回资源之前使用这些信息来了解有关资源的信息。
对于这种请求您可以做的最简单的事情就是简单地输出所有的响应头的内容。

function updatePage() {
     if (request.readyState == 4) {
       alert(request.getAllResponseHeaders());
     }
   }

您可以单独使用这些头(从服务器类型到内容类型)在 Ajax 应用程序中提供其他信息或功能。

检查 URL
您已经看到了当 URL 不存在时应该如何检查 404 错误。如果这变成一个常见的问题 —— 可能是缺少了一个特定的脚本或 servlet —— 那么您就可能会希望在生成完整的 GET 或 POST 请求之前来检查这个 URL。要实现这种功能,生成一个 HEAD 请求,然后在回调函数中检查 404 错误。

function updatePage() {
     if (request.readyState == 4) {
       if (request.status == 200) {
         alert("URL exists");
       } else if (request.status == 404) {
         alert("URL does not exist.");
       } else {
         alert("Status is: " + request.status);
       }
     }
   }

有用的 HEAD 请求
您会发现 HEAD 请求非常有用的一个领域是用来查看内容的长度或内容的类型。这样可以确定是否需要发回大量数据来处理请求,和服务器是否试图返回二进制数据,而不是 HTML、文本或 XML(在 JavaScript 中,这 3 种类型的数据都比二进制数据更容易处理)。
在这些情况中,您只使用了适当的头名,并将其传递给 XMLHttpRequest 对象的 getResponseHeader() 方法。因此要获取响应的长度,只需要调用 request.getResponseHeader("Content-Length");。要获取内容类型,请使用 request.getResponseHeader("Content-Type");。

原创粉丝点击