网络请求之XMLHttpRequest

283 阅读2分钟

微信公众号:  [大前端驿站]
关注大前端驿站。问题或建议,欢迎公众号留言。 这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战

我们在日常工作中经常用到Axios和Fecth来请求数据,虽然XMLHttpRequest已经是过时的API,实际开发中我们基本也不会用到它,但是面试偶尔也会被问到,建议还是要有一定的理解。

所有现代浏览器都通过 XMLHttpRequest 构造函数原生支持 XHR 对象。

使用 XHR 对象首先要调用 open()方法,这个方法接收 3 个参数:请求类型("get"、"post"等)、请求 URL,以及表示请求是否异步的布尔值。

let xhr = new XMLHttpRequest()
xhr.open("get", "example.txt", false); 

这行代码就可以向 example.txt 发送一个同步的 GET 请求。关于这行代码需要说明几点。首先,这里的 URL 是相对于代码所在页面的,当然也可以使用绝对 URL。其次,调用 open()不会实际发送请求,只是为发送请求做好准备。 要发送定义好的请求,必须像下面这样调用 send()方法

xhr.open("get", "example.txt", false)
xhr.send(null)

send()方法接收一个参数,是作为请求体发送的数据。如果不需要发送请求体,则必须传 null,因为这个参数在某些浏览器中是必需的。调用 send()之后,请求就会发送到服务器。

注意:因为这个请求是同步的,所以 JavaScript 代码会等待服务器响应之后再继续执行

收到响应后,XHR对象的以下属性会被填充上数据

  • responseText:作为响应体返回的文本。
  • responseXML:如果响应的内容类型是"text/xml"或"application/xml",那就是包含响应数据的 XML DOM 文档。
  • status:响应的 HTTP 状态。
  • statusText:响应的 HTTP 状态描述。

收到响应后,第一步要检查 status 属性以确保响应成功返回。一般来说,HTTP 状态码为 2xx 表示成功。此时,responseText 或 responseXML(如果内容类型正确)属性中会有内容。如果 HTTP状态码是 304,则表示资源未修改过,是从浏览器缓存中直接拿取的。当然这也意味着响应有效。为确保收到正确的响应,应该检查这些状态,如下所示:

xhr.open("get", "example.txt", false);
xhr.send(null);
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
 alert(xhr.responseText);
} else {
 alert("Request was unsuccessful: " + xhr.status);
} 

虽然可以像前面的例子一样发送同步请求,但多数情况下最好使用异步请求,这样可以不阻塞JavaScript 代码继续执行。XHR 对象有一个 readyState 属性,表示当前处在请求/响应过程的哪个阶段。readyState属性有如下可能的值

  • 0:未初始化(Uninitialized)。尚未调用 open()方法。
  • 1:已打开(Open)。已调用 open()方法,尚未调用 send()方法。
  • 2:已发送(Sent)。已调用 send()方法,尚未收到响应。
  • 3:接收中(Receiving)。已经收到部分响应。
  • 4:完成(Complete)。已经收到所有响应,可以使用了。

每次 readyState 从一个值变成另一个值,都会触发 readystatechange 事件

let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            alert(xhr.responseText);
        } else {
            alert("Request was unsuccessful: " + xhr.status)
        }
    }
};
xhr.open("get", "example.txt", true)
xhr.send(null)

在收到响应之前如果想取消异步请求,可以调用 abort()方法:

xhr.abort()

调用这个方法后,XHR 对象会停止触发事件,并阻止访问这个对象上任何与响应相关的属性。中断请求后,应该取消对 XHR 对象的引用




~~ 感谢观看

关注下方【大前端驿站】
让我们一起学,一起进步

【分享、点赞、在看】三连吧,让更多的人加入我们