• 使用axios 封装大文件上传,支持断点续传的功能


    使用 Axios 实现断点续传、重试、暂停、开始和上传进度功能

    简介

    在许多应用程序中,我们经常需要上传大文件。但是,由于网络连接不稳定或其他原因,上传过程可能会中断。为了解决这个问题,我们可以使用断点续传功能。断点续传允许我们在上传中断后从中断处继续上传文件,而无需重新上传整个文件。

    除了断点续传,我们还可以使用重试、暂停和开始功能来更好地控制上传过程。重试功能允许我们在上传失败时自动重试上传。暂停功能允许我们暂停正在进行的上传。开始功能允许我们开始新的上传。

    此外,我们还可以使用上传进度功能来实时跟踪上传进度。这对于大文件上传非常有用,因为它可以让我们知道上传的进展情况。

    实现

    我们可以使用 Axios 库来轻松实现断点续传、重试、暂停、开始和上传进度功能。Axios 是一个流行的 JavaScript 库,它可以帮助我们轻松地发送 HTTP 请求。

    首先,我们需要安装 Axios 库。我们可以使用以下命令来安装 Axios:

    npm install axios
    
    • 1

    安装完成后,我们就可以在我们的代码中使用 Axios 了。

    以下是如何使用 Axios 实现断点续传、重试、暂停、开始和上传进度功能的示例代码:

    import axios from 'axios';
    
    // 断点续传
    const resumeUpload = (file, chunkSize, fileId, endpoint) => {
      // 获取已上传的字节数
      const uploadedBytes = file.slice(0, chunkSize).byteLength;
    
      // 创建一个新的 FormData 对象
      const formData = new FormData();
    
      // 将文件块添加到 FormData 对象中
      formData.append('file', file.slice(uploadedBytes));
    
      // 将文件 ID 和已上传的字节数添加到 FormData 对象中
      formData.append('fileId', fileId);
      formData.append('uploadedBytes', uploadedBytes);
    
      // 发送请求以继续上传文件
      return axios.post(endpoint, formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });
    };
    
    // 重试
    const retryUpload = (file, chunkSize, fileId, endpoint) => {
      // 获取已上传的字节数
      const uploadedBytes = file.slice(0, chunkSize).byteLength;
    
      // 创建一个新的 FormData 对象
      const formData = new FormData();
    
      // 将文件块添加到 FormData 对象中
      formData.append('file', file.slice(uploadedBytes));
    
      // 将文件 ID 和已上传的字节数添加到 FormData 对象中
      formData.append('fileId', fileId);
      formData.append('uploadedBytes', uploadedBytes);
    
      // 发送请求以重试上传文件
      return axios.post(endpoint, formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });
    };
    
    // 暂停
    const pauseUpload = () => {
      // 取消正在进行的上传请求
      axios.cancel();
    };
    
    // 开始
    const startUpload = (file, chunkSize, endpoint) => {
      // 创建一个新的 FormData 对象
      const formData = new FormData();
    
      // 将文件块添加到 FormData 对象中
      formData.append('file', file.slice(0, chunkSize));
    
      // 发送请求以开始上传文件
      return axios.post(endpoint, formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });
    };
    
    // 上传进度
    const uploadProgress = (progressEvent) => {
      // 计算上传进度
      const progress = (progressEvent.loaded / progressEvent.total) * 100;
    
      // 更新进度条
      document.getElementById('progress-bar').value = progress;
    };
    
    • 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
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    使用示例:

    // 文件对象
    const file = document.getElementById('file-input').files[0];
    
    // 块大小(以字节为单位)
    const chunkSize = 1024 * 1024; // 1MB
    
    // 文件 ID(唯一标识符)
    const fileId = '1234567890';
    
    // 端点 URL
    const endpoint = 'https://example.com/upload';
    
    // 开始上传文件
    startUpload(file, chunkSize, endpoint)
      .then((response) => {
        // 获取文件 ID
        const fileId = response.data.fileId;
    
        // 上传文件块
        for (let i = 1; i < Math.ceil(file.size / chunkSize); i++) {
          // 获取文件块
          const fileChunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
    
          // 上传文件块
          resumeUpload(fileChunk, chunkSize, fileId, endpoint)
            .then((response) => {
              // 更新上传进度
              uploadProgress(response.data.progress);
            })
            .catch((error) => {
              // 重试上传文件块
              retryUpload(fileChunk, chunkSize, fileId, endpoint);
            });
        }
      })
      .catch((error) => {
        // 处理错误
        console.error(error);
      });
    
    // 暂停上传文件
    document.getElementById('pause-button').addEventListener('click', () => {
      pauseUpload();
    });
    
    • 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
    • 41
    • 42
    • 43
    • 44
  • 相关阅读:
    某些按钮,用click函数来点击无效果,这个时候用鼠标模拟点击试试!
    如何使用Matplotlib模块的text()函数给柱形图添加美丽的标签数据?
    Linux 基本语句_6_C语言_文件操作
    VL53L5CX驱动开发(4)----运动指示器
    2023.10.08
    基于51单片机的智能路灯控制系统(lunwen+设计说明+仿真+程序)
    Vite5+Vue3整合Tailwindcss详细教程
    进程的优先级与LAMP项目部署实战
    链表的反转-leetcode
    dlv调试kubelet
  • 原文地址:https://blog.csdn.net/weixin_42657666/article/details/136291953