• Ajax四


    Ajax 处理服务端响应

    在浏览器发送 Ajax 请求之后,下一步骤自然是服务器响应。服务器在接收到请求之后会进行一系列处理步骤,最终返回结果。而与此同时,客户端会在接收到返回的结果之后进行界面的展示或者数据的处理。

    本章节主讲 Ajax 收到返回数据后处理服务器响应过程。

    前言

    本章节将会从两个方面来讲解 Ajax 如何处理服务端响应,它们分别是:

    • 处理的时机
    • 处理的方法

    如果你不知道 Ajax 是如何获取服务端响应内容的,或者你对 HTTP 状态码没有一个初步的了解,甚至你还不知道一个 Ajax 请求过程中各个阶段的状态表示,那么,我相信这个章节会很适合你。接下来让我们步入正题,一起来看看 Ajax 是如何处理服务端响应的。

    1. 何时处理响应

    首先思考一个问题,我们应该在什么时机处理服务端的响应呢?

    我们知道,Ajax 可以发送异步请求,那数据的返回当然也不可能是同步返回的。客户端只有等到服务端数据返回才能进行数据的下一步处理。如果服务端没有正确响应,或者说服务端的响应还没结束,那么客户端是无法获得正确响应的。讲得俏皮一点,客户端在这个时候还得看服务端的脸色。

    那么,在代码中我们要在什么样的时机开始处理响应呢?

    这里,我们有必要了解一下 XMLHttpRequest.readyState 和 XMLHttpRequest.status

    1.1 XMLHttpRequest.readyState

    在客户端与服务器的通信过程中,XMLHttpRequest.readyState 体现着当前请求以及服务端响应的状态。当 xhr.readyState == 4 的时候,代表着服务器响应完成。

    其他的 readyState 状态码还有 0 、1、2、3,他们分别代表着:

    0:状态为 UNSENT。表示创建了但还没有调用 open 方法。

    1:状态为 OPENED。表示已经调用了 open 方法。

    2:状态为 HEADERS_RECEIVED。表示已经调用了 send 方法,且头部和状态也可获得。

    3:状态为 LOADING。表示正在下载中。

    4:状态为 DONE。表示响应已经完成。

    从 readyState 的状态码来看,总共有 5 个状态。并且只有最后一个状态 4 才能代表着可以开始处理服务端响应数据的时机。

    1.2 XMLHttpRequest.status

    服务器响应完成之后,我们通常会使用 XMLHttpRequest.status 来查看当前 XMLHttpRequest 响应中的数字状态码。这个数字状态码是一个无符号短整型状态码,代表着我们的 Ajax 请求的状态成功与否。

    在 XMLHttpRequest 中, status 码对应着标准的 HTTP 状态码。并且在请求完成前,该值为 0。

    HTTP 状态码很多,这里就不做过多的铺开,具体可以到 HTTP 响应代码 进行学习和查阅。接下来我们来讲几个常见的状态码。

    是的,这也是很常见的两个状态码。

    1.2.1 200 和 304 状态码

    在 HTTP 状态码中,200 代表着 HTTP 请求成功,而 304 代表着由于浏览器缓存原因,GET 请求命中并返回了缓存中的数据。结合 上面 XMLHttpRequest.readyState , 假设请求成功,我们的响应模块应该如下:

    xhr.open("GET", "http://localhost:8080/simple/get?mk=慕课网");
    
    xhr.send();
    
    xhr.onreadystatechange = function() {
        // 当前 this 为 xhr
        if (this.readyState == 4) {
            if (this.status === 200 || this.status === 304) {
    			// code ...
            }
        }
    };
    
    

    在后端设置了协商缓存的情况下,我们来看看效果:

    第一次请求资源:

    图片描述

    刷新页面,进行第二次请求同样的资源:

    图片描述
    由于浏览器的缓存机制,GET请求有可能会缓存我们的请求内容。上面前后两次请求中,第一次请求的时候获取新的内容,返回的是 200 的状态码;而第二次再进行获取,我们就有可能获取第二图的结果,使用的是本地缓存。因此,在对 Ajax 成功的判断中,我们不应该遗漏 304 状态码的判断。

    1.2.2 404 和 500 状态码

    有正确的返回,那当然也会有错误的返回。打个比方,让我们来假设这样的场景:

    • 客户端发送一个请求,刚好请求的接口找不到,因为服务端并没有提供。
    • 客户端发送一个请求,服务端内部发生错误了。

    如果遇到这样的情况,Ajax 当然不能坐以待毙——我们总不该不把任何响应告诉用户吧!真实的情况是,Ajax 会返回我们相应的 status ,客户端根据该 status 进行必要的操作。

    首先,我们来请求一个捏造的接口,即服务端并没有支持的接口。

    html 关键容器:

    <div id="container"></div>
    

    JavaScript 脚本关键代码:

    var container = document.getElementById('container')
    xhr.onreadystatechange = function() {
        // 当前 this 为 xhr
        if (this.readyState == 4) {
            if (this.status === 200 || this.status === 304) {
                container.innerHTML = "当前状态码为: " + this.status;
            } else {
                container.innerHTML = "当前错误状态码为: " + this.status; // 主要看这里,出现非 200 和 304 状态会在这边进行显示
            }
        }
    };
    

    看看运行后的效果图:

    图片描述

    404 Not Found,显而易见,当我们在查询的时候,服务端找不到对应的资源的时候就会返回该状态码,表示你要找的东西没有,不存在。在我们的实际工作中,我们经常会遇到这样的错误,往往这个时候你就应该警惕:

    • 是不是你的请求 url 写错了?
    • 是不是前后端线上资源不同步?比方说后端还没上线对应接口而你已经在开始在代码中请求了。

    讲完 404 状态码,我们接下来继续来看看一个很常见的场景,服务器内部发生错误了!!!代码沿用上一个示例,接口改为服务端提供的接口,这次我们会在服务端假设发生错误,并返回 500 错误。

    来看看请求的结果:

    图片描述

    事实上,500 错误码也是非常常见的,500 Internal Server Error 代表着服务端错误,如果我们在开发过程中遇到这样的错误,那么,就需要后端的同学来查找原因了。

    除此之外,HTTP 状态码还有很多,每个都有不同的含义,这里也不会做过多的展开,有兴趣的同学可以做一个额外的学习查阅。HTTP 协议中,状态码可以让我们在请求之后,获知请求的状态。客户端也能够以此做出相应的响应。

    2. 如何获取响应内容

    要获取响应内容,当然是 XMLHttpRequest 对象下的几大法器:responseText 、 responseXML 和 response。其中:

    • responseText: 一个 DomString,返回一个纯文本的值。 当该值为 “” 的时候,表示这个请求还没有开始 send();当该值为 null 的时候,表示请求失败。
    • responseXML: 处理 XML 响应。返回一个包含请求检索的 HTML 和 XML 的 Document。 当请求还没有 send(),或者失败了,甚至是解析失败的时候,该值为 null 。当 responseType 不是 “” 或者 "document"的时候,会报错。
    • response: 返回响应正文。返回类型可以有 DOMString、 Blob 、ArrayBuffer 、Document 或 JavaScript Object ,这取决于 responseType。

    了解获取响应内容的这 3 个属性,接下来,我们会分别返回 DomString、XML 和 Json 类型数据来展示着响应内容。

    核心响应代码:

    xhr.onreadystatechange = function() {
        if (this.readyState == 4) {
            if (this.status === 200 || this.status === 304) {
                var res = this.response
                var resText = this.responseText
                var resXml = this.responseXML
                console.log(res, resText, resXml) // 分别打印三者
            }
        }
    };
    

    2.1 返回 DomString

    服务端返回内容:

    ‘text’
    

    请求结果:

    图片描述

    Content-type:

    图片描述

    可以看到,当返回的是一个 DomString 的时候,responseText 和 response 都有值,而 responseXML 因为解析失败为 null。

    2.2 返回 XML

    服务端返回内容:

    <data>Hello World</data>
    

    请求结果:

    图片描述

    Content-type:

    图片描述

    这一次我们的 XML 正常解析了,并且在控制台上可以看到打印出了一个 Document,而 response 和 responseText 分别打印了该 XML 的文本形式。

    2.3 返回 Json

    服务端返回内容:

    {a:1}
    

    请求结果:

    图片描述

    Content-type:

    图片描述

    当返回的是一个 Json 类型数据的时候,response 和 responseText 分别为对应的文本值,而 responseXML 因为解析失败成了 null。

    以上展示了 Ajax 获取服务端响应的三种类型的数据,简单的展示给大家 XMLHttpRequest 的 response、responseText 和 responseXML 在不同数据类型下的表现,希望以此能够加深大家对 XMLHttpRequest 的了解。

    3. 小结

    • 处理 Ajax 请求,我们应该在适当的时机进行处理。我们应该在 xhr.readyState == 4 ,并且 xhr.status === 200 || xhr.status === 304 的时候正确获取响应的内容;
    • XMLHttpRequest.readyState 体现着当前请求以及服务端响应的状态;
    • XMLHttpRequest.status 即 XMLHttpRequest 响应中的数字状态码。这个数字状态码是一个无符号短整型状态码,代表着我们的 Ajax 请求的状态成功与否;
    • HTTP 状态码有很多,包括 404、 500 等,每一个包含着不一样的含义;
    • 获取服务器响应内容,我们可以使用 responseText 、 responseXML 和 response 。其中,responseText 返回一个纯文本的值,responseXML 返回一个包含请求检索的 HTML 和 XML 的 Document,而 response 返回响应正文。返回类型可以有 DOMString、 Blob 、ArrayBuffer 、Document 或 JavaScript Object ,这取决于 responseType。
  • 相关阅读:
    用Doxygen生成X3D的继承关系树
    FreeBSD 8.0候选版本RC2发布
    Mozilla Firefox, Apple Safari,Chrome等主流浏览器均开始WebGL支持
    关于企业管理信息系统
    [转]WebGL标准最新进展
    C++ + Irrlicht整一个东东?
    FreeWRL Windows Beta版本注记
    选择C++开发环境
    老人与老浏览器-李开复与成熟度最高的VRML浏览器SGI Cosmo
    WebGL概念及HTML5推广给X3D规范带来的新出路
  • 原文地址:https://www.cnblogs.com/liunaiming/p/13052138.html
Copyright © 2020-2023  润新知