AJAX
AJAX
AJAX并非编程语言,而是一种使用现有技术集合的方法。这些技术包括 HTML
或 XHTML
, CSS
, JavaScript
, DOM
, XML
, XSLT
, 以及最重要的XMLHttpRequest
。AJAX的全称为 Asynchronous JavaScript And XML
,意为异步JavaScript和XML
AJAX是如何工作的
AJAX的工作方式是在后台与服务器进行少量数据交换,这使得网页可以在不重新加载整个网页的情况下,对网页的某部分进行更新。这种技术在浏览器运行,使用浏览器与web服务器之间的异步数据传输,使网页从服务器请求少量的信息,而不是整张页面
XMLHttpRequest
XMLHttpRequest
是AJAX的基础,也是最核心的部分,它是一个内置对象,允许我们使用 JavaScript 发送 HTTP
请求,虽然它的名字里面有 XML
一词,但它可以操作任何数据,而不仅仅是 XML
格式。我们可以用它来上传/下载文件,跟踪请求进度等
创建 XHR 对象
const xhr = new XMLHttpRequest();
初始化请求
xhr.open(method, URL, [async, user, password]);
open
方法有三个参数:
- method:请求的类型;包含
GET
、POST
、PUT
、DELETE
等 - URL:一个
url
字符串,表示请求的地址 - async:一个可选的布尔参数,表示是否异步执行操作,默认为
true
。如果值为false
,send()
方法直到收到答复前不会返回 - user、password:可选的用户名和密码,用于身份验证用途,默认为
null
设置请求头
XMLHttpRequest 允许发送自定义 header
,并且可以从响应中读取 header
,header
必须在 open()
之后 send()
之前设置
//xhr.setRequestHeader(header, value);
xhr.setRequestHeader('Content-Type', 'application/json');
setRequestHeader
方法用于设置请求头,它有两个参数:
- header:请求头的名称
- value:请求头的值
header 会以单行的形式返回,header 之间的换行符为 \r\n
,并且 header 的 name
与 value
之间总是用以冒号后跟一个空格 :
来分隔,获取header的方法有两种:
xhr.getResponseHeader(name)
:获取给定名称的响应头xhr.getAllResponseHeaders()
:获取所有响应头
Cache-Control: max-age=31536000
Content-Length: 2480
Content-Type: application/json
Date: Sat, 09 Sep 2023 16:53:16 GMT
当想要将获取到的 header 处理成为可用的对象,需要额外使用一些JS方法来处理:
const headers = xhr
.getAllResponseHeaders()
.split('\r\n')
.reduce((result, current) => {
let [name, value] = current.split(': ');
result[name] = value;
return result;
}, {});
这样就可以获得一个标准的 header 对象了
设置请求超时
xhr.timeout = 3000;
超时设置会在请求耗时超过给定的超时事件后,自动终止请求,并将 readyState
属性设置为 4,同时触发 timeout
事件
设置响应类型
xhr.responseType = 'json';
responseType
属性用于设置响应的数据类型,它接受以下值:
''
:空字符串,默认值,代表响应的数据类型为text
'text'
:代表响应的数据类型为text
'arraybuffer'
:代表响应的数据类型为ArrayBuffer
'blob'
:代表响应的数据类型为Blob
'document'
:代表响应的数据类型为Document
'json'
:代表响应的数据类型为JSON
'text'
:代表响应的数据类型为text
发送请求
xhr.send([body]);
send
方法有一个可选的参数 [body]
,它的默认值是 null
,它还可以取以下的值:
- 可以为 Document, 在这种情况下,它在发送之前被序列化
- 可以为 XMLHttpRequestBodyInit, Blob,BufferSource, FormData, URLSearchParams, 或者 USVString 对象
XHR 请求状态
XMLHttpRequest.status
代表了 xhr 请求的状态。status
的值是一个无符号的数字类型。在请求完成前,status 的值为 0。如果请求出错,浏览器返回的 status 也为 0。status 码是标准的 HTTP status code
常见的 HTTP status code
请看文章最后
XHR 事件监听
//监听 XHR 加载事件
xhr.onload = function(){
console.log(`status: ${xhr.status}`);
console.log(xhr.response);
}
//监听 XHR 错误事件
xhr.onerror = function(){
console.log('Request failed');
}
//监听 XHR 加载进度事件
xhr.onprogress = function(event){
// event.loaded —— 已经下载了多少字节
// event.lengthComputable = true,当服务器发送了 Content-Length header 时
// event.total —— 总字节数(如果 lengthComputable 为 true)
console.log(`Received ${event.loaded} of ${event.total} bytes`);
}
在 xhr 对象上,上面示例中的3个事件是最常用的:
load
事件:请求成功完成时触发error
事件:请求失败时触发,例如网络中断或者无效的 URLprogress
事件:请求接收到更多数据时触发,可以获取到请求进度
XHR 状态监听
xhr 对象的状态会随着它的处理进度的变化而变化,xhr 对象提供了 readyState
属性,用来表示它的请求状态,它有5个可能的值:
- 0:请求未初始化(UNSENT)
- 1:服务器连接已建立(OPENED)
- 2:请求已接收(HEADER_RECEIVED)
- 3:请求处理中(LOADING)
- 4:请求已完成,且响应已就绪(DONE)
当 readyState
属性的值发生变化时,会触发 readystatechange
事件:
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
console.log(xhr.responseText);
} else {
console.log(`Error: ${xhr.status}`);
}
}
}
跟踪上传进度
在上面的示例中,我们介绍了 onprogress
事件,它用来监听请求(下载)的进度,但是有时我们在上传文件时,也会想要监听上传的进度,这时可以使用 xhr.upload
对象来进行监听
xhr.upload
对象有以下事件,会在不同的上传阶段触发:
loadstart
:上传开始时触发progress
:上传过程中不断触发abort
:上传被中断时触发error
:上传失败时触发load
:上传成功完成时触发loadend
:上传完成时触发timeout
:上传超时触发(如果设置了 timeout 属性)
// 监听上传进度
xhr.upload.onprogress = function(event){
if(event.lengthComputable){
console.log(`Received ${event.loaded} of ${event.total} bytes`);
}
}
// 监听上传完成
xhr.upload.onload = function() {
console.log(`Upload finished successfully.`);
}
// 监听上传失败
xhr.upload.onerror = function() {
console.log(`Error during the upload: ${xhr.status}`);
}
// 监听上传中断
xhr.upload.onabort = function() {
console.log(`The upload has been aborted`);
}
终止 XHR 请求
xhr.abort();
abort
方法会终止请求,并将 xhr 的 readyState
属性与 status
重置为 0
常见状态码
状态 | 类型 | 描述 |
---|---|---|
100 | 信息响应 | Continue(继续)。客户端应继续其请求 |
101 | 信息响应 | Switching Protocols(切换协议)。服务器根据客户端的请求切换协议 |
200 | 成功响应 | OK。请求成功。一般用于GET与POST请求 |
201 | 成功响应 | Created。成功请求并创建了新的资源 |
204 | 成功响应 | No Content。服务器成功处理,但未返回内容 |
301 | 重定向 | Moved Permanently。请求的资源已被永久的移动到新URI |
302 | 重定向 | Found。此响应代码表示所请求资源的URI已暂时更改 |
400 | 客户端错误 | Bad Request。客户端请求的语法错误,服务器无法理解 |
401 | 客户端错误 | Unauthorized。请求要求用户的身份认证 |
403 | 客户端错误 | Forbidden。服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | 客户端错误 | Not Found。服务器无法根据客户端的请求找到资源(网页等) |
500 | 服务器错误 | Internal Server Error。服务器内部错误,无法完成请求 |
502 | 服务器错误 | Bad Gateway。作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 |
503 | 服务器错误 | Service Unavailable。由于超载或系统维护,服务器暂时的无法处理客户端的请求 |
更多关于 AJAX 的信息,请参考 XMLHTTPRequest