Ajax 全称 Asynchronous JavaScript and XML( 异步 JavaScript 和 XML ),早在 2005 年就被提出,它被描述为一种使用现有技术集合的‘新’方法,包括的技术有:HTML、CSS、JavaScript、DOM、XML 以及最重要的 XMLHttpRequest,它可以在不重新加载整个页面的情况下与服务器交换数据并更新部分网页内容

Ajax 的核心是异步数据交换,通过 Ajax 我们可以向服务器发送 HTTP 请求( 如 GET、POST 等 ),并处理响应( 包括 JSON、XML、HTML等 )

XMLHttpRequest 对象

XMLHttpRequest 对象是对 Ajax 异步数据交换的实现

基本用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 创建 XMLHttpRequest 类型对象
let xhr = new XMLHttpRequest();

// 初始化一个请求,设置请求方法和目标 URL
xhr.open('GET', 'https://api.example.com/data');

// 注册事件监听器,处理响应
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) { // 请求完成
if (xhr.status === 200) { // 请求成功,xhr.status 获取响应状态码
console.log('成功响应:', xhr.responseText); // xhr.responseText 获取响应的文本数据
} else {
console.error('请求失败,状态码: ' + xhr.status);
}
}
};

// 发送请求
xhr.send();

XMLHttpRequest 的常用方法:

  1. xhr.open(method, url)
    • method:请求方法(如 GETPOST
    • url:请求的目标 URL
  2. xhr.send(data):发送请求,如果是 GET 请求,data 通常为 null;如果是 POST 请求,可以在这里发送请求体数据
  3. xhr.setRequestHeader(header, value):设置 HTTP 请求头,例如设置 Content-Typeapplication/json
  4. xhr.getResponseHeader(name):获取 HTTP 响应头
  5. xhr.abort():取消当前的请求
  6. xhr.responseType:响应体的类型,默认 text 类型
    • arraybuffer:response 是一个包含二进制数据的 js ArrayBuffer
    • blob:response 是一个包含二进制数据的 Blob 对象
    • document:response 是一个 Document 对象( 如:HTML Document、XMLDocument )
    • json:response 是一个 js 对象
    • text:response 是一个普通文本( 字符串 )
  7. xhr.response:获取响应体
  8. xhr.responseText:获取响应体,只有当 responseTypetext"" 时,xhr 对象上才有此属性
  9. xhr.responseXML:获取响应体只,有当 responseTypetext""document 时,xhr 对象上才有此属性

readystatechange 事件:

readystatechange 事件在 readyState 属性每次变化时 都会触发,因此它可以处理整个请求的生命周期

readyState 具有 5 种状态:

  1. 0: 请求尚未初始化,open() 方法还未被调用
  2. 1: 服务器连接已建立,此时可以可以开始发送请求了
  3. 2: 请求已接收,响应头和响应状态已经返回
  4. 3: 请求处理中(正在接收响应数据),此时 xhr.response 中可能已经有了响应数据
  5. 4: 请求已完成,传输结束

load 事件:

load 事件在 请求完成且成功接收到服务器响应后 触发。换句话说,当请求的 readyState 达到 4(完成)并且状态码为 200 代表成功时,onload 会被调用

发送 POST 请求

例1:

1
2
3
4
5
6
7
8
9
10
11
/* 例1 发送 form-urlencoded 类型数据 */
const xhr = new XMLHttpRequest();

// 初始化一个请求,并设置请求方法为 POST
xhr.open('POST', 'https://api.example.com/data');

// 设置请求头,Content-Type 请求体类型, 如果发送 JSON, 则设置 application/json
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

// 发送请求(包含请求体)
xhr.send('a=1&b=2&c=3')

超时处理

可以通过 timeout 事件来处理请求超时,当请求在设定的时间内未能完成,触发 timeout 事件

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const xhr = new XMLHttpRequest();

xhr.open('GET', 'https://api.example.com/data');

// 设置请求超时时间,单位是毫秒
xhr.timeout = 5000; // 5秒超时

// 定义 ontimeout 事件
xhr.ontimeout = function() {
console.error('The request for https://api.example.com/data timed out.');
};

// 定义 onerror 事件处理程序, 当网络请求发送错误时触发
xhr.onerror = function() {
alert('An error occurred during the transaction');
};

// 发送请求
xhr.send();

error 事件:

error 事件会在请求失败时被调用。它处理的是与请求本身相关的网络问题,比如服务器未响应、断网等

发送文件

例:

1
2
3
4
<form id="uploadForm">
<input type="file" id="fileInput" name="file" />
<button type="button" onclick="uploadFile()">Upload File</button>
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
function uploadFile() {
// 获取文件输入元素
const fileInput = document.getElementById('fileInput');

// 获取选择的文件
const file = fileInput.files[0];

// 创建一个 FormData 对象
const formData = new FormData();

// 将文件追加到 FormData 对象中
formData.append('file', file);

// 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();

// 初始化 POST 请求,目标为上传文件的服务器 API
xhr.open('POST', '/upload', true);

// 设置 onload 事件处理器,当上传成功时执行
xhr.onload = function() {
if (xhr.status === 200) {
console.log('File uploaded successfully!');
} else {
console.error('Error uploading file');
}
};

// 处理错误和超时的情况
xhr.onerror = function() {
console.error('Request failed');
};

xhr.ontimeout = function() {
console.error('Request timed out');
};

// 发送 FormData 对象,其中包含要上传的文件
xhr.send(formData);
}

进度监听

XMLHttpRequest 支持追踪上传和下载的进度,可以通过 progress 事件来监听进度

例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let xhr = new XMLHttpRequest();

xhr.open('GET', 'https://api.example.com/file');

// 设置 progress 进度监听事件,如果要监听上传的进度,可以使用 xhr.upload.onprogress
xhr.onprogress = function (event) {
// event.lengthComputable:表示下载的数据长度是否是可计算的(即是否知道数据的总大小)。如果为 true,表示服务器已发送的响应中包含了数据的总大小,能够计算出下载的进度
if (event.lengthComputable) {
// event.loaded:表示当前已经下载的字节数
// event.total:表示数据的总大小(以字节为单位)。这个值只有在 lengthComputable 为 true 时才有效
let percentComplete = (event.loaded / event.total) * 100;
console.log(`下载进度: ${percentComplete}%`);
}
}

// 发送请求
xhr.send();

xhr.upload.onprogress 事件会在上传阶段( 即xhr.send()之后,xhr.readystate=2之前 )触发,每50ms触发一次;xhr.onprogress 事件会在下载阶段( 即xhr.readystate=3时 )触发,每50ms触发一次

XMLHttpRequest 其它事件

  • onloadstart:获取开始,调用xhr.send()方法后立即触发,若xhr.send()未被调用则不会触发此事件
  • onabort:获取操作终止,当调用xhr.abort()后触发
  • onloadend:获取完成,当请求结束(包括请求成功和请求失败)时触发

Axios

Axios 是一个基于 Promise 的 HTTP 网络请求库,可在 Node.js 和 浏览器环境中使用,在浏览器环境中则是基于 XMLHttpRequest 对象实现

使用 Axios

首先,我们要引入 Axios。可以通过 CDN 链接引入,或者使用 npm 安装:

通过 <script src="CDN_LINK"></script> 引入:

1
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

通过 npm 安装:

1
npm install axios

基本用法

发送 GET 请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
发送 GET 请求
@param URL {String} 请求的url地址
@param options {Object} 请求配置项
@return {Promise}
*/
axios.get('https://api.example.com/posts', {
// 设置 URL 参数, axios 会把 params 中的键值对用 ? 和 & 拼接成 urlencode 格式的字符串, 然后传入 URL 中发送给服务器
params: {
id: 1
}
}).then(function (response) {
// 请求成功处理
console.log(response.data);
}).catch(function (error) {
// 请求失败处理
console.error(error);
});

// 使用 async/await
async function fetchData() {
try {
const response = await axios.get('https://api.example.com/posts', {
params: {
id: 1
}
});
console.log(response.data);
} catch (error) {
console.error(error);
}
}

fetchData();

发送 POST 请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
发送 POST 请求
@param URL {String} 请求的url地址
@param body {String|Object} 请求体
@return {Promise}
*/
axios.post('https://api.example.com/posts', {
title: 'foo',
body: 'bar',
userId: 1
}).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});

/*
axios 会自动将 Object 转换为 JSON 格式, 并自动将 Content-Type 头设置为 application/json, 然后发送给服务器
*/