前言
AJAX(Asynchronous JavaScript and XML) 是一种用于在网页上进行异步通信的技术。它允许在不刷新整个页面的情况下,通过在后台与服务器进行数据交换来更新部分网页内容。
正文
1. 原生能力边界
- XHR:完整支持请求和响应的进度监控
- Fetch:仅支持响应进度监控(请求进度暂不支持)
- 所有第三方库(如axios)都是基于原生API实现的,能力不会超过原生
2. 响应进度监控实现
AJAX实现方式:
xhr (axios基于xhr)
fetch (umi-reuqest基于fetch)
XHR 方案:
js
const xhr = new XMLHttpRequest();
xhr.addEventListener('progress', (e) => {
// e.loaded 已接收字节数
// e.total 总字节数
const percent = (e.loaded / e.total * 100).toFixed(2);
console.log(`进度: ${percent}%`);
});
Fetch 方案:
js
const response = await fetch(url);
// 从响应头获取总大小
const total = +response.headers.get('Content-Length');
let loaded = 0;
const reader = response.body.getReader();
while(true) {
const {done, value} = await reader.read();
if(done) break;
loaded += value.length; // 累加已接收字节
console.log(`进度: ${(loaded/total*100).toFixed(2)}%`);
}
3. 请求进度监控(仅XHR支持)
js
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (e) => {
// 上传进度监控
const percent = (e.loaded / e.total * 100).toFixed(2);
console.log(`上传进度: ${percent}%`);
});
完整代码,加个进度条:
js
// 创建一个新的XMLHttpRequest对象,用于与服务器交互
const xhr = new XMLHttpRequest();
// 初始化一个GET请求,请求的URL是'https://example.com'
// 第三个参数true表示请求是异步的(非阻塞)
xhr.open('GET', 'https://example.com', true);
// 设置onprogress事件处理函数,在请求接收数据过程中周期性触发
xhr.onprogress = function(event) {
// 检查是否能够计算数据长度
if (event.lengthComputable) {
// 计算已完成加载的百分比
const percentComplete = (event.loaded / event.total) * 100;
// 在控制台输出当前加载进度
console.log('Progress: ' + percentComplete + '%');
} else {
// 如果无法计算数据长度,输出未知进度
console.log('Progress: unknown');
}
};
// 设置onload事件处理函数,当请求成功完成时触发
xhr.onload = function() {
// 在控制台输出请求完成的信息
console.log('Request finished!');
};
// 发送请求到服务器
xhr.send();
这段代码演示了如何使用XMLHttpRequest对象:
-
创
建请求对象
-
配
置请求方法
和URL
-
设
置进度监控回调
-
设置
完成回调
-
发送请求
主要用于监控文件下载等长时间请求的进度情况。
4. 关键差异点
- XHR 通过事件机制获取进度
- Fetch 需要手动处理可读流
- 大文件上传必须用XHR获取精确进度
- Fetch 响应进度监控需要理解流式API
5. 实际应用建议
- 简单场景:优先使用Fetch + 响应进度
- 需要上传进度:必须使用XHR
- 超大文件考虑分片上传方案
理解这些底层原理,才能在不同业务场景选择合适的技术方案。现代前端开发中,虽然Fetch API越来越普及,但XHR在某些场景下仍是不可替代的选择。