使用js写一个方法实现文件上传的断点续传功能

实现文件上传的断点续传功能是一个相对复杂的任务,涉及前端和后端的协同工作。在前端,你主要需要处理文件的切片、上传进度跟踪、暂停/恢复上传以及错误处理等。以下是一个简化的前端实现示例,使用原生JavaScript和XMLHttpRequest进行文件上传。

class ChunkedUploader {
  constructor(file, url, options = {}) {
    this.file = file;
    this.url = url;
    this.chunkSize = options.chunkSize || 1024 * 1024; // 默认1MB
    this.chunks = [];
    this.currentChunk = 0;
    this.paused = false;
    this.progress = 0;

    // 计算文件分片
    for (let i = 0; i < Math.ceil(this.file.size / this.chunkSize); i++) {
      this.chunks.push({
        index: i,
        start: i * this.chunkSize,
        end: Math.min(this.file.size, (i + 1) * this.chunkSize),
        uploaded: false,
      });
    }
  }

  // 上传分片
  uploadChunk(chunk) {
    const xhr = new XMLHttpRequest();
    const formData = new FormData();
    const blob = this.file.slice(chunk.start, chunk.end);
    formData.append('file', blob, this.file.name);
    formData.append('index', chunk.index);
    xhr.open('POST', this.url, true);
    xhr.upload.onprogress = (event) => {
      if (event.lengthComputable) {
        // 更新进度(可根据需要自定义)
        console.log(`Chunk ${chunk.index}: ${(event.loaded / event.total) * 100}%`);
      }
    };
    xhr.onload = () => {
      if (xhr.status === 200) {
        chunk.uploaded = true;
        this.progress = this.chunks.reduce((acc, curr) => acc + (curr.uploaded ? 1 : 0), 0) / this.chunks.length;
        console.log(`Chunk ${chunk.index} uploaded successfully. Overall progress: ${this.progress * 100}%`);
        this.uploadNextChunk(); // 上传下一个分片
      } else {
        console.error(`Chunk ${chunk.index} upload failed with status ${xhr.status}`);
        // 错误处理,如重试等
      }
    };
    xhr.onerror = () => {
      console.error(`Chunk ${chunk.index} upload encountered an error`);
      // 错误处理,如重试等
    };
    if (!this.paused) {
      xhr.send(formData); // 开始上传分片
    }
  }

  // 上传下一个未上传的分片
  uploadNextChunk() {
    const nextChunk = this.chunks.find((chunk) => !chunk.uploaded);
    if (nextChunk) {
      this.currentChunk = nextChunk.index;
      this.uploadChunk(nextChunk); // 上传找到的分片
    } else {
      console.log('All chunks uploaded successfully'); // 所有分片上传完成
    }
  }

  // 开始/恢复上传
  start() {
    this.paused = false;
    if (this.currentChunk === 0) { // 如果是首次开始,则从头开始上传
      this.uploadNextChunk(); // 上传第一个分片
    } else { // 否则,继续上传当前分片(断点续传)
      const currentChunk = this.chunks[this.currentChunk];
      if (!currentChunk.uploaded) { // 如果当前分片未上传完,则继续上传该分片
        this.uploadChunk(currentChunk); // 上传当前分片(断点续传)
      } else { // 如果当前分片已上传完,则上传下一个分片(防止因网络等原因导致的上传状态不一致)
        this.uploadNextChunk(); // 上传下一个分片(断点续传后的正常流程)
      }
    }
  }

  // 暂停上传
  pause() {
    this.paused = true; // 设置暂停标志,阻止后续上传操作(需配合XHR的abort方法使用,此处简化处理)
    console.log('Upload paused'); // 输出暂停信息(可根据需要自定义)
  }
}

使用方法:

const input = document.querySelector('input[type="file"]'); // 获取文件输入元素(可根据需要自定义)
input.addEventListener('change', (event) => {
  const file = event.target.files[0]; // 获取选中的文件(可根据需要自定义)
  const uploader = new ChunkedUploader(file, 'your-upload-endpoint'); // 创建ChunkedUploader实例,传入文件和上传接口URL(需替换为实际值)
  uploader.start(); // 开始上传文件(可根据需要自定义调用时机和方式)
  // uploader.pause(); // 暂停上传文件(可根据需要自定义调用时机和方式,如添加暂停按钮等)
});

注意:上述代码是一个简化的前端实现示例,主要展示了文件分片、上传进度跟踪和基本的暂停/恢复上传功能。在实际应用中,你还需要考虑更多的细节和异常情况,如网络错误重试、分片上传的并发控制、与后端服务器的通信协议等。此外,后端服务器也需要相应地支持断点续传功能,能够接收并处理分片上传的请求。

posted @   王铁柱6  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示