资讯专栏INFORMATION COLUMN

20170615-Ajax和XMLHttpRequest

Java3y / 3186人阅读

摘要:从请求开始算起,若超过时间请求还没有结束包括成功失败,则会触发事件,主动结束该请求。在不限制超时的情况下,有可能同步请求一直处于状态,服务端迟迟不返回响应,这样整个页面就会一直阻塞,无法响应用户的其他交互。

Ajax和XMLHttpRequest

这篇文章转发自我之前的一篇博客,是看过《你真的会使用XMLHttpRequest吗?》后结合自己之前对Ajax认识的总结。

Ajax:"Asynchronous JavaScript And XML"即异步JavaScript和XML,是一种创建交互式网页应用的网页开发技术,这项技术的核心是浏览器提供的XMLHttpRequest对象。

XMLHttpRequest的使用 1.设置request header void setRequestHeader(headerName, headerValue)

setRequestHeader必须写在open()方法之后,send()方法之前

2. 获取response header getAllResponseHeaders()

获取全部可获取(有一些header是获取不到的)的header字段

getResponseHeader(headerName)

获取指定header字段的值(只能获取部分header的值)

3. 指定xhr.response的数据类型

通过设置xhr.response的类型,是告诉浏览器或者xhr如何处理响应数据(对响应数据按照什么样的格式去处理)

xhr.overrideMimeType()

这个方法的作用就是重写response的MIME类型

这个方法必须在send()方法之前进行调用

可以通过这种方式,可以得到纯文本格式的图片内容,获取到数据后再使用相应的编码方法重新构建图片

var xhr = new XMLHtppRequest()
xhr.open("get", "text.php", true)
xhr.overrideMimeType("text/xml; charset=utf-8")
xhr.send();

根据上面的例子,将response的MIME类型设置为了"text/xml",通过这样的方式,xhr会将响应当做text或者xml来处理,通过xhr.responsexhr.responseText可以获取到文本格式的相应数据,通过xhr.responseXML可以获取到XML格式(是一颗DOM树/DOM对象)的数据

var xhr = new XMLHtppRequest()
xhr.open("get", "text.php", true)
xhr.overrideMimeType("text/plain; charset=utf-8")
xhr.send();

根据上面的例子,将response的MIME类型设置为了"text/plain",通过这样的方式,xhr会将相应当做text或者plain(纯文本)来处理,通过xhr.responsexhr.responseText可以获取到文本格式的相应数据,通过xhr.responseXML获取到的数据为null,即便数据是XML

xhr.responseType

responseType是XMLHttpRequest leve2中新增的属性,用来指定xhr.response的数据类型

var xhr = new XMLHttpRequest();
xhr.open("GET", "/path/to/image.png", true);
//可以将`xhr.responseType`设置为`"blob"`也可以设置为`" arrayBuffer"`
//xhr.responseType = "arrayBuffer";
xhr.responseType = "blob";

xhr.onload = function(e) {
  if (this.status == 200) {
    // this.response就是Blob对象
    var blob = this.response;
    ...
  }
};

xhr.send();
4. 如何获取response数据

xhr提供了3个属性来获取请求返回的数据,分别是:xhr.response, xhr.responseText, xhr.responseXML

xhr.response:

无论xhr.responseType的值是什么,只要请求完成,都可以从xhr.response中取到对应的值

请求未完成时,xhr.response的值与xhr.responseType有关,xhr.responseType的值为""(默认值)或者text时,xhr.response的值为"",否则为null

xhr.responseText:

只有当responseType设置为""或者text时,才可以使用这个属性获取相应内容

请求未完成、失败时,该值为空字符串

xhr.responseXML:

只有当 responseType 为""document时,此时才能调用xhr.responseXML,否则抛错

请求未完成、失败时,该值为null

5. 如何追踪ajax请求的当前状态

xhr.readyState属性可以获取ajax的状态,每当xhr.readyState的值发生变化时,就会触发xhr.onreadystatechange事件,可以在这个事件中进行相应的操作

为了保证跨浏览器兼容性,必须在调用open()方法之前指定onreadystatechange事件处理程序

 xhr.onreadystatechange = function () {
    switch(xhr.readyState){
      case 1://OPENED
        //do something
            break;
      case 2://HEADERS_RECEIVED
        //do something
        break;
      case 3://LOADING
        //do something
        break;
      case 4://DONE
        //do something
         break;
    }

6. 设置请求的超时时间

XMLHttpRequest提供了timeout属性来允许设置请求的超时时间。

从请求开始 算起,若超过 timeout 时间请求还没有结束(包括成功/失败),则会触发ontimeout事件,主动结束该请求。

请求开始:xhr.onloadstart事件触发的时候,也就是你调用xhr.send()方法的时候

请求结束:xhr.loadend事件触发的时候。

7. 发送同步请求

由open()方法的第三个参数决定,当第三个参数async为true时,发送异步请求,为false时则为同步请求

当xhr为同步请求时,有如下限制:

xhr.timeout必须为0

xhr.withCredentials必须为 false

xhr.responseType必须为""(即默认值)

避免使用同步请求:因为我们无法设置请求超时时间(xhr.timeout为0,即不限时)。在不限制超时的情况下,有可能同步请求一直处于pending状态,服务端迟迟不返回响应,这样整个页面就会一直阻塞,无法响应用户的其他交互。

8. 如何获取上传、下载进度

我们可以通过onprogress事件来实时显示进度,默认情况下这个事件每50ms触发一次。需要注意的是,上传过程和下载过程触发的是不同对象的onprogress事件:

上传触发的是xhr.upload对象的 onprogress事件

下载触发的是xhr对象的onprogress事件

xhr.onprogress = updateProgress;
xhr.upload.onprogress = updateProgress;
function updateProgress(event) {
    if (event.lengthComputable) {
      var completedPercent = event.loaded / event.total;
    }
 }
xhr相关事件

每一XMLHttpRequest对象都有一个upload属性,而upload是一个XMLHttpRequestUpload对象.XMLHttpRequest和XMLHttpRequestUpload对象共同拥有上述(除onreadystatechange事件)事件。onreadystatechange是XMLHttpRequest对象独有的事件

1. 事件触发顺序

触发xhr.onreadystatechange(之后每次readyState变化时,都会触发一次)

触发xhr.onloadstart

上传阶段开始:

触发xhr.upload.onloadstart

触发xhr.upload.onprogress

触发xhr.upload.onload

触发xhr.upload.onloadend

上传结束,下载阶段开始:

触发xhr.onprogress

触发xhr.onload

触发xhr.onloadend

2. 发生abort/timeout/error异常的处理

一旦发生abort或timeout或error异常,先立即中止当前请求

将 readystate 置为4,并触发 xhr.onreadystatechange事件

如果上传阶段还没有结束,则依次触发以下事件:

xhr.upload.onprogress

xhr.upload.[onabort或ontimeout或onerror]

xhr.upload.onloadend

注意不会触发onload事件

触发 xhr.onprogress事件

触发 xhr.[onabort或ontimeout或onerror]事件

触发xhr.onloadend 事件

注意不会触发onload事件

注意: 这时候的xhr.readyState为4,xhr.status为0

3. 在哪个事件中注册成功回调

从上面介绍的事件中,可以知道若xhr请求成功,就会触发xhr.onreadystatechange和xhr.onload两个事件。由于xhr.onreadystatechange是每次xhr.readyState变化时都会触发,而不是xhr.readyState=4时才触发(例如发生abort、timeout、error异常,会先终止当前请求,将readyState设置为4,并触发onreadystatechange事件),因此建议在onload事件中注册成功回调

xhr.onload = function () {
    //如果请求成功
    if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      //do successCallback
    }
  }
为什么要对xhr.status进行上述判断

xhr.status代表相应的HTTP状态
以2开头的状态码,代表请求已经成功被服务器接收、理解、并接受
状态代码304代表请求的资源并没有修改,可以直接使用浏览器中缓存的版本
其他以3开头的状态代码则表示需要客户端采取进一步的操作才能完成请求。

status和readyState

status是响应的HTTP状态,statusText是HTTP状态的说明

readyState是表示在请求/响应过程中的当前活动处于哪个阶段

参考文章

你真的会使用XMLHttpRequest吗?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83459.html

相关文章

  • XMLHttpRequest快餐

    摘要:一次完整的请求对于很多对象来说,都会有状态,事件和方法。其中的状态和事件其实就是对象的属性。下载的事件属于对象,上传的事件属于对象。事件传输被用户取消。返回所有响应头信息响应头名和值如果响应头还没接受则返回重写由服务器返回的。 XMLHttpRequest可解释为可扩展超文本传输请求。它是一个浏览器Api,为客户端提供了在客户端和服务器之间传输数据的功能。使得Javascript可以进...

    2shou 评论0 收藏0
  • 你不知道的 XMLHttpRequest

    摘要:默认参数为空字符串密码,可选参数,用于授权。默认参数为空字符串备注如果不是有效的方法或地址不能被成功解析,将会抛出异常如果请求方法不区分大小写为或将会抛出异常重写由服务器返回的类型。 本文详细介绍了 XMLHttpRequest 相关知识,涉及内容: AJAX、XMLHTTP、XMLHttpRequest详解、XMLHttpRequest Level 1、Level 2 详解 XHR...

    ckllj 评论0 收藏0
  • ajax的原生实现-XMLHttpRequest

    摘要:的交互原理则是请求事件目标从而到达后端事件目标。事件目标对请求事件进行验证实现业务逻辑,最后可以响应处理结果与前端交互。 ajax 即Asynchronous Javascript And XML(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。当初JavaScript的变革就是ajax的出现而改变。在现代web领域对数据的异步加载和局部更新上也在大...

    liaoyg8023 评论0 收藏0
  • AJAX总结(三),XMLHttpRequest对象

    摘要:包括对象的本质,请求和响应。下例为小张发送给大元的便条,存储为。表的值常量值含义尚未调用已经调用接收到头信息接收到响应主体响应完成为了监听事件,请把事件处理函数设置为对象的属性。响应包状态码,响应头和响应主体。 前言 博主博客:Stillwater的博客知乎专栏:前端汪汪本文为作者原创转载请注明出处: http://hiztx.top/2017/01/13/a...   这篇文章介绍...

    DrizzleX 评论0 收藏0

发表评论

0条评论

Java3y

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<