前端大文件上传

89 阅读2分钟

前端大文件上传

大文件上传基本思路

  • 将大文件转换成二进制流的格式(当你通过 <input type="file"> 元素选择文件时,浏览器已经为你提供了一个 File 对象,这个对象本质上就是一个包含文件内容的二进制大对象(Blob),这一步就省略了)。
  • 利用文件 Blob 原型上的 slice 方法进行切割,将二进制流切割成多份,将得到的切片数 组 chunkList 添加一些信息,比如文件名和下标,得到 uploadChunkList
  • 组装和分割块同等数量的请求块,并行或串行的形式发出请求
  • 待我们监听到所有请求都成功发出去以后,再给服务端发出一个合并的信号

秒传

秒传指的是已经上传过的文件,不必重复传输,可以直接从后台取回文件资源。 前端实现思路如下:

  • 用户选择要上传的文件
  • 计算文件的hash值,利用hash值判断该文件是否已经存在
  • 如果已经存在,直接从后台获取该文件资源,上传结束
  • 如果不存在,则走正常的分片上传流程

断点续传

  • 为每一个文件切割块添加不同的标识
  • 当上传成功的之后,记录上传成功的标识
  • 当我们暂停或者发送失败后,可以重新发送没有上传成功的切割文件

进度条

xhr中提供了上传进度的事件progress,如果项目中使用的是axios ,axios在配置时提供了onUploadProgress监听原生progress事件。

var xhr = new XMLHttpRequest();  
  
// 监听上传进度  
xhr.upload.onprogress = function(event) {  
    if (event.lengthComputable) {  
        var percentComplete = (event.loaded / event.total) * 100;  
        console.log('Upload progress: ' + percentComplete.toFixed(2) + '%');  
    }  
};  
  
// 监听下载进度  
xhr.onprogress = function(event) {  
    if (event.lengthComputable) {  
        var percentComplete = (event.loaded / event.total) * 100;  
        console.log('Download progress: ' + percentComplete.toFixed(2) + '%');  
    }  
};  

后端

  • 接收每一个切割文件,并在接收成功后,存到指定位置,并告诉前端接收成功

  • 收到合并信号,将所有的切割文件排序,合并,生成最终的大文件,然后删除切割小文件,并告知前端大文件的地址