XMLHttpRequest

760 阅读3分钟

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」。

XMLHttpRequest

IE5 是第一个引入 XHR 对象的浏览器。这个对象是通过 ActiveX 对象实现并包含在 MSXML 库中 的。为此,XHR 对象的 3 个版本在浏览器中分别被暴露为 MSXML2.XMLHttp、MSXML2.XMLHttp.3.0 和 MXSML2.XMLHttp.6.0。

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

let xhr = new XMLHttpRequest();

XHR

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

xhr.open("get", "example.php", false); 

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

跨域问题: 这里只能访问同源 URL,也就是域名相同、端口相同、协议相同。如果请求的 URL 与 发送请求的页面在任何方面有所不同,则会抛出安全错误。

要发送定义好的请求,必须像下面这样调用 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 表 示成功,如果 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); 
}

XHR 对象有一个 readyState 属性,表示当前处在请求/响应过程的哪个阶段。 这个属性有如下可能的值。

状态名称描述
0Uninitialized初始化状态。XMLHttpRequest 对象已创建或已被 abort() 方法重置。
1Openopen() 方法已调用,但是 send() 方法未调用。请求还没有被发送。
2SentSend() 方法已调用,HTTP 请求已发送到 Web 服务器。未接收到响应。
3Receiving所有响应头部都已经接收到。响应体开始接收但未完成。
4LoadedHTTP 响应已经完全接收。

当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);

注意 由于 onreadystatechange 事件处理程序的作用域问题,这个例子在 onreadystatechange 事件处理程序中使用了 xhr 对象而不是 this 对象。使用 this 可能导致 功能失败或导致错误,取决于用户使用的是什么浏览器。因此还是使用保存 XHR 对象的 变量更保险一些。

abort()

取消当前响应,关闭连接并且结束任何未决的网络活动。

这个方法把 XMLHttpRequest 对象重置为 readyState 为 0 的状态,并且取消所有未决的网络活动。例如,如果请求用了太长时间,而且响应不再必要的时候,可以调用这个方法。