前端做网络请求是基于AJAX的,Ajax有两种方式:
XMLHttpRequest: 简称XHR,比较常用的axios就是基于XMLHttpRequest封装的
fetch:新的api,它相对应的第三方库是umi-request
浏览器原生的就支持这两种请求。其他库都是基于这两种去封装的。
fetch文档比较中可以看出来,它无法实现请求进度的监控,因为fetch是基于promise的,promise只有成功和失败,所以进度监控是难以处理的。
XMLHttpRequest进度监控
function xhr_request(options={}) {
const {url, method='GET', onProgress, data=null} = options;
return new Promise(async (resolve, reject)=> {
const xhr = XMLHttpRequest();
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = ()=> {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject({status: xhr.status, message: '请求失败'})
}
}
}
// xhr.onprogress = onProgress;
// 或
xhr.addEventListener('progress', e => {
console.log(e.loaded, e.total);
onProgress &&
onProgress({
loaded: e.loaded,
total: e.total
});
});
//监控文件上传的进度
// xhr.upload.onprogress = onProgress;
// 或
xhr.upload.addEventListener('progress', onProgress);
// 建立请求连接
xhr.open(method, url);
// 发送请求,data则为请求参数
xhr.send(data);
});
}
fetch进度监控
function fetch_request(options={}) {
const {url, method='GET', onProgress, data=null} = options;
return new Promise(async (resolve)=> {
const resp = await fetch(url, {
method,
body: data
});
// 获取总的数据量
const total = +resp.headers.get('content-length');
const decoder = new TextDecoder();
let body = '';
// 获取数据流的读取器
const reader = resp.body.getReader();
let loaded = 0;
while(1) {
// value是buffer类型
const {done, value} = await reader.read();
if(done) {
// 数据读取完成则退出循环
break;
}
loaded += value.length;
// buffer解码
body += decoder.decode(value);
onProgress && onProgress({loaded, total});
}
resolve(body);
});
}