前端文件上传进度指南

Last Modified: 2022/09/16

前言

前端经常有上传文件或者图片的需求,当图片或文件较大时,为了更好的用户体验,往往需要显示进度条。本文将会讲述 xhr/axios 中如何监听文件上传进度。

XMLHttpRequest

XMLHttpRequest(xhr),是早期流行的在浏览器和 web 服务器之前传输数据的接口对象。xhr中提供了 progress 事件,监听方法如下:

const xhr = new XMLHttpRequest();
// 监听进度
xhr.upload.addEventListener('progress', function(progressEvent) {
  let e = progressEvent;
  if (lengthComputable) {
    const percent = e.loaded / e.total;
    console.log(`当前进度:${percent.toFixed(2)}%`);
  }
});

xhr.open("GET", url);
xhr.send();

可以看出借助于 ProgressEvent 对象,可以轻松计算出进度百分比。ProgressEvent 对象的属性说明:

  • lengthComputable:布尔类型,用于表示进度是否可以计算,true 可以计算,有些情况下,进度是不可以计算的,具体可以参考这里
  • loaded:64无符号整形,表示底层已经处理完毕的工作量。
  • total: 总工作量,用 loaded/total 可以得到进度。

axios

目前比较流行的基于 Promise 的 HTTP client。监听进度的方法如下:

const config = {
  onUploadProgress: function(progressEvent) {
    let e = progressEvent
    var percent = Math.round((e.loaded * 100) / e.total)
    console.log(`上传进度:${percent}`)
  }
}

let data = new FormData()
data.append('file', file)

await axios.put('/your/upload/endpoint', data, config)

需要说明的,在虑浏览器环境中,axios 底层使用的 XMLHttpRequest,因此进度计算方式和 XHR 相同。

下面的代码是从 axios 源码中摘录的,从中可以看出 axios 中进度就是封装自原始的 XHR。

let req = new XMLHttpRequest();
// ...省略1w行代码
if (typeof config.onUploadProgress === 'function' && req.upload) {
    req.upload.addEventListener('progress', progressEventReducer(config.onUploadProgress));
}

fetch

暂时还不支持,只能借助于 axios 或者 XHR 来实现。

有问题吗?点此反馈!

温馨提示:反馈需要登录