【vue2+js】通过js实现大文件分片上传和合并上传

本文介绍了如何使用前端技术如Blob、File和FormData对象进行大文件分片上传,包括MD5加密、分片处理、接口调用和合并分片的过程,以及处理不同文件格式的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么要分片上传

在这里插入图片描述
上传大文件(比如3GB)时,一般不能调用一次接口上传完,接口会超时或报错,这时候需要前端把大文件分片处理一下,再分别调用接口上传分片文件,全部分片上传完后,由后端将所有分片合并和返回最终的文件地址。

实现思路

  • 在进行分片上传前,需要对文件进行md5加密,生成md5码,在后面每次调用接口时以formData格式上传给接口
  • 然后定义初始化信息,比如分片大小、开始和结束的文件大小、索引
  • 接着执行定义好的分片函数,传入初始化好的文件信息:uploadChunk(file, start, end, index);
  • 最后执行uploadChunk(file, start, end, index),先调用分片接口上传分片文件,所有分片文件全部上传后调用合并分片接口,该接口会返回整个文件上传后最终的地址
    • file.slice(start, end)直接对文件进行分片,第一次分片的start是0,也就是文件开始位置,end是分片的大小(如果文件没有分片大就是文件大小)
    • 在文件分片后,将分片信息以formData格式作为参数传给分片接口
    • 在接口成功响应后,更新开始和结束位置、index自增:开始位置更新为上次的结束位置大小,结束位置更新为上次的结束位置加一个分片后的大小(如果加起来比文件大,结束位置就是整个文件大小),
    • 判断是不是最后一个分片:比较start 和 file.size大小,如果更新后的文件开始大小比整个文件小,递归调用uploadChunk,传入更新后的参数,直到所有分片都上传;如果更新后的文件开始大小比整个文件大(即上次end结束位置已经上传全部分片了),说明分片已经全部上传完了,不再调用分片接口,调用合并分片接口,获取最终的整个文件地址
  async handleAvatarUploadDemo({
    
     file }) {
   
   
     .....
     //MD5加密
     const md5 = await this.handleFile(file);
     const chunkSize = 10 * 1024 * 1024; // 10MB 每个分片的大小
     let start = 0;
     let end = Math.min(chunkSize, file.size);
     let index = 0;

     const uploadChunk = (file, start, end, index) => {
   
   
       const chunk = file.slice(start, end); // 切割文件为分片
       let formData = new FormData();
       formData.append('file', chunk);
       formData.append('index', index);
       formData.append('totalChunks', Math.ceil(file.size / chunkSize));
       formData.append('md5', md5);
       axios
         .post(
           '/api/spang-system/oss/endpoint/put-file-flake',
           formData, // 直接传递formData对象
           {
   
   
             headers: {
   
    'Content-Type': 'multipart/form-data' },
             timeout: 600000,
           }
         )
         .then(res => {
   
   
           // 处理分片上传成功的响应

           index++;
           start = end;
           end = Math.min(start + chunkSize, file.size);

           if (file.size - start < 5 * 1024 * 1024 && start !== 0) {
   
   
             // 最后一个切片大小小于5MB且不是第一个切片
             start = end;
             end = file.size; // 设置结束位置为文件末尾start = Math.max(0, end - chunkSize); // 重新计算起始位置        
           }

           if (start < file.size) {
   
   
             uploadChunk(file, start, end, index); // 递归上传下一个分片,并传递file参数
           } else {
   
   
             // 所有分片上传完成
             // 合并分片等操作
             const param = {
   
    md5: md5, originalFilename: file
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值