第九章 JavaScript 异步编程专题 9.2 XMLHttpRequest

168 阅读10分钟

9.2 XMLHttpRequest异步请求对象

XMLHttpRequest对象是JavaScript中处理HTTP请求的核心,它提供了向服务器发送HTTP请求和获取响应的方法和属性。XMLHttpRequest对象的使用方法如下: 创建XMLHttpRequest对象 let xhr = new XMLHttpRequest(); 创建后,可以使用该对象执行各种HTTP请求。

创建请求

XMLHttpRequest对象的open()方法用于创建一个新的HTTP请求,参数如下: xhr.open(method, url, async, user, password)

method:指定HTTP请求的方法,比如GET、POST、PUT等。 url:请求的URL地址。 async:是否采用异步方式,默认为true(即异步方式)。 user:可选参数,表示用户名,用于进行HTTP认证。 password:可选参数,表示密码,用于进行HTTP认证。 例如,下面的代码用GET方式请求一个JSON文件:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/data.json');

HTTP协议定义了多种请求方法,常用的有以下几种: 1 GET:请求指定资源。GET请求的参数会附加在URL上发送给服务器。 2 POST:向指定资源提交数据进行处理请求,数据在请求体中。 3 PUT:向指定资源位置上传其最新内容。 4 DELETE:请求服务器删除指定的资源。 5 HEAD:获取资源的元数据信息,与GET请求类似,但不返回响应体。 6 OPTIONS:查询服务器支持的HTTP请求方法以及支持的其他选项。 7 CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 8 TRACE:回显服务器收到的请求,用于测试或诊断。 除了上述方法外,HTTP/1.1协议还定义了其他方法,例如PATCH、PROPFIND、PROPPATCH、MKCOL等。

设置Header

在使用XMLHttpRequest对象进行HTTP请求时,可以使用setRequestHeader()方法来设置HTTP请求头部。该方法接收两个参数,第一个参数是HTTP请求头部的名称,第二个参数是HTTP请求头部的值。例如,以下代码演示了如何在HTTP请求中设置自定义的Authorization头部: xhr.setRequestHeader('Authorization', 'Bearer your_access_token'); HTTP协议中常用的header有: Content-Type:指定HTTP请求或响应中的实体的MIME类型,常用的有

  • application/json:JSON 数据
  • application/x-www-form-urlencoded:HTML 表单数据,经过 URL 编码的键值对
  • multipart/form-data:带有文件上传的 HTML 表单数据
  • text/plain:纯文本数据
  • image/png、image/jpeg、image/gif:图片数据
  • application/pdf:PDF 数据
  • application/xml:XML 数据 User-Agent:标识发起HTTP请求的客户端类型和版本号,可以用于统计分析等目的。 Referer:表示当前请求的源地址,通常用于防盗链和统计分析等场景。 Accept-Encoding:指定能够接收的内容编码方式,如gzip、deflate等。 Authorization:用于传递认证信息,如Basic认证、Token认证等。 Cache-Control:用于控制缓存的行为,如no-cache、max-age等。 Cookie:表示当前请求的cookie信息,通常用于身份验证和状态管理等场景。 Host:表示请求的目标服务器的域名或IP地址和端口号。 If-Modified-Since:用于条件请求,表示只有当指定时间之后资源发生过变化时才返回响应。 Range:表示请求资源的范围,用于实现断点续传等功能。

设置body发送请求

xhr.send() 是 XMLHttpRequest 对象的一个方法,用于将请求发送到服务器。它接收一个参数,可以是一个字符串,也可以是一个 FormData 对象或者是一个 ArrayBufferView。 当我们需要向服务器发送一个 POST 请求,需要将一些数据发送给服务器时,就可以使用 xhr.send() 方法,将数据放在该方法的参数中进行传递。 示例代码如下:

let xhr = new XMLHttpRequest();
let data = {
  name: 'John',
  age: 20
};
xhr.open('POST', '/user', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));

上述代码中,我们使用 xhr.send() 方法将一个对象转换成 JSON 字符串并作为参数发送到服务器。在 xhr.setRequestHeader() 方法中,我们设置了请求头中的 Content-Type 为 application/json,告诉服务器接收到的是一个 JSON 字符串。 监听请求的状态 xhr.onreadystatechange是XMLHttpRequest对象的一个事件,该事件会在XMLHttpRequest对象的readyState属性发生变化时触发。 readyState属性表示XMLHttpRequest对象的状态,可能的取值有以下几种:

  • 0: 未初始化。XMLHttpRequest对象已创建,但尚未调用open()方法。
  • 1: 打开。open()方法已调用,但尚未调用send()方法。
  • 2: 已发送。send()方法已调用,但尚未收到响应。
  • 3: 接收中。已经接收到部分响应数据。
  • 4: 完成。已经接收到全部响应数据,并且可以在客户端使用了。 当readyState属性的值发生变化时,xhr.onreadystatechange事件就会被触发。可以通过判断readyState属性的值,来确定XMLHttpRequest对象的状态,以便采取相应的操作。通常,当readyState属性的值为4时,表示XMLHttpRequest对象的操作已经完成,此时可以获取响应数据。 以下是一个使用 xhr.onreadystatechange 的例子:
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText);
  }
};
xhr.open("GET", "https://jsonplaceholder.typicode.com/posts/1");
xhr.send();

在这个例子中,我们创建了一个新的 XMLHttpRequest 对象,设置了 xhr.onreadystatechange 事件处理函数。当 xhr.readyState 变为 4(即已经接收到了响应)并且 xhr.status 为 200(即请求成功)时,我们通过 xhr.responseText 获取响应的文本内容,并将其输出到控制台中。 然后我们调用 xhr.open 方法设置 HTTP 请求的方法和 URL,最后使用 xhr.send 方法发送请求。当服务器返回响应时,xhr.onreadystatechange 事件处理函数会被触发,并执行我们定义的代码块。 注意需要先绑定事件再调用send方法发送请求。

请求完成事件

XMLHttpRequest的load事件在XMLHttpRequest成功完成请求时触发。也就是说,当HTTP状态码为2xx(成功)时,load事件将被触发。 load事件通常用于检查响应,并将其传递给其他函数进行处理。例如,你可以在load事件处理程序中获取响应的文本,然后将其转换为JavaScript对象,以便更轻松地操作。以下是使用XMLHttpRequest的load事件的示例代码:

const xhr = new XMLHttpRequest();
xhr.onload = function() {
  if (xhr.status === 200) {
    const data = JSON.parse(xhr.responseText);
    console.log(data);
  }
};
xhr.open('GET', 'https://example.com/api/data');
xhr.send();

在此示例中,我们将请求发送到API端点,并在响应成功返回时使用JSON.parse将响应文本转换为JavaScript对象。我们还使用XMLHttpRequest的status属性检查响应的状态码,以确保响应成功。

获取Http返回信息

一般是在 onreadystatechange的事件中获取http返回的信息。 status 获取http的状态码 status 是 XMLHttpRequest 对象的只读属性,表示请求的 HTTP 状态码。 HTTP 状态码是由服务端返回的三位数字,用于表示客户端请求的处理结果。常见的状态码有: 2xx 成功:表示客户端的请求被服务端正确处理; 3xx 重定向:表示客户端需要进行额外的操作才能完成请求; 4xx 客户端错误:表示客户端的请求有错误,常见的错误有 404(未找到)、403(禁止访问)、401(未授权)等; 5xx 服务端错误:表示服务端处理请求时出现错误,常见的错误有 500(服务端内部错误)、503(服务端不可用)等。 在 XMLHttpRequest 发送请求后,可以通过 xhr.status 来获取请求的状态码,从而判断请求是否成功。一般情况下,状态码在 200 到 299 之间表示请求成功。

statusText 获取http状态说明

XMLHttpRequest 对象的 statusText 属性是一个只读属性,它表示在处理请求时 HTTP 状态的说明。statusText 的值是一个字符串,包含了状态码对应的文本描述,例如,当状态码是 404 时,statusText 的值就是 "Not Found"。 responseText获取http返回的文本内容 XMLHttpRequest对象的responseText属性表示响应数据的文本内容。它返回一个字符串,通常用于处理文本类型的响应,如HTML、XML、JSON等。 注意,responseText只能获取到文本形式的响应数据, 并且responseType属性必须是默认值空字符串""或者是"text"时 才可以获取该属性,否则会报错。同时,在获取responseText前需要确保请求已经完成(即readyState值为4),否则它将返回空字符串。如果请求未能成功返回,responseText也将返回空字符串。

response获取返回主体内容

XMLHttpRequest对象的response属性用于获取响应体数据。它可以返回多种类型的数据,包括文本、JSON、XML、二进制数据等。数据类型的返回值取决于返回的Content-Type头和responseType属性的设置。 responseType属性是XMLHttpRequest对象的属性,表示期望从服务器接收哪种类型的数据。可以设置的值包括: ""或"text":""是默认值,返回文本数据。 "json":返回JSON格式对象。 "document":返回XML文档数据。 "arraybuffer":返回二进制数据。 "blob":返回Blob对象。 当返回的Content-Type头与responseType属性期望的数据类型不一致时,response属性的值将为null。例如,当responseType属性设置为json时,但响应体不是有效的JSON数据时,response属性将为null。如果不指定xhr.responseType,则response属性的值将根据服务器返回的Content-Type自动转换成相应的类型,如文本或JSON格式的字符串、XML文档、二进制数据等。如果服务器返回的Content-Type无法识别,则response属性为null,所以建议都显式的指定responseType以免出现意外情况。 以下是几个示例:

// 返回文本数据
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.onload = function() {
  console.log(xhr.responseType); // text
  console.log(xhr.response); // 返回文本数据
};
xhr.send();

// 返回JSON数据
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.responseType = 'json';
xhr.onload = function() {
  console.log(xhr.responseType); // json
  console.log(xhr.response); // 返回JSON数据
};
xhr.send();

// 返回XML文档数据
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.responseType = 'document';
xhr.onload = function() {
  console.log(xhr.responseType); // document
  console.log(xhr.response); // 返回XML文档数据
};
xhr.send();

// 返回二进制数据
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
  console.log(xhr.responseType); // arraybuffer
  console.log(xhr.response); // 返回二进制数据
};
xhr.send();

// 返回Blob对象
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data');
xhr.responseType = 'blob';
xhr.onload = function() {
  console.log(xhr.responseType); // blob
  console.log(xhr.response); // 返回Blob对象
};
xhr.send();

需要注意的是,response属性的值只能在load事件触发后才能获取到。如果在load事件触发前尝试访问response属性,它的值将为null。

获取http返回的header

要获取XMLHttpRequest对象返回的响应头信息,可以使用XMLHttpRequest对象的getResponseHeader()和getAllResponseHeaders()方法。 getResponseHeader(header)方法用于获取指定的响应头信息,需要传入参数header,表示要获取的响应头名称,返回值为指定的响应头信息。如果响应中没有指定的头,则返回null。 getAllResponseHeaders()方法用于获取所有响应头信息,返回值为一个字符串,包含所有响应头信息。每个响应头都由名称和值组成,中间用冒号和空格隔开。多个响应头之间用换行符(\n)隔开。 以下是一个获取响应头信息的例子:

const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com');
xhr.onload = function() {
  console.log(xhr.getResponseHeader('Content-Type'));
  console.log(xhr.getAllResponseHeaders());
}
xhr.send();

error事件

在进行XMLHttpRequest请求时,如果出现错误,就会触发error事件。这个事件通常是用来处理网络请求错误、服务器错误、跨域等问题。 下面是一个XMLHttpRequest error事件的示例:

const xhr = new XMLHttpRequest();
xhr.addEventListener('error', function() {
  console.log('Error occurred');
});
xhr.open('GET', 'https://example.com/api');
xhr.send();

在这个示例中,如果在发送请求时出现错误,就会触发error事件,并打印出"Error occurred"。但是我们通常都会在onreadystatechange中根据readyState和status来处理错误的情况。