作者:凹凸实验室 链接:https://juejin.im/post/5ebb4346e51d451ef53793ad
整体思路
第一步是结合项目背景,调研比较优化的解决方案。 文件上传失败是老生常谈的问题,常用方案是将一个大文件切片成多个小文件,并行请求接口进行上传,所有请求得到响应后,在服务器端合并所有的分片文件。当分片上传失败,可以在重新上传时进行判断,只上传上次失败的部分,减少用户的等待时间,缓解服务器压力。这就是分片上传文件。
大文件上传
那么如何实现大文件分片上传呢?
流程图如下:
![9d0c41605d00fce63c086930995b2323.png](https://i-blog.csdnimg.cn/blog_migrate/b99ece9d6fe28576b94b187b44844c09.jpeg)
分为以下步骤实现:
1. 文件 MD5 加密
MD5 是文件的唯一标识,可以利用文件的 MD5 查询文件的上传状态。
根据文件的修改时间、文件名称、最后修改时间等信息,通过 spark-md5 生成文件的 MD5。需要注意的是,大规格文件需要分片读取文件,将读取的文件内容添加到 spark-md5 的 hash 计算中,直到文件读取完毕,最后返回最终的 hash 码到 callback 回调函数里面。这里可以根据需要添加文件读取的进度条。
![831d788df624d5d3938eded2819f4501.gif](https://i-blog.csdnimg.cn/blog_migrate/0cb278a36ca2a44ce06a6c646610bc61.gif)
实现方法如下:
// 修改时间+文件名称+最后修改时间-->MD5md5File (file) { return new Promise((resolve, reject) => { let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice let chunkSize = file.size / 100 let chunks = 100 let currentChunk = 0 let spark = new SparkMD5.ArrayBuffer() let fileReader = new FileReader() fileReader.onload = function (e) { console.log('read chunk nr', currentChunk + 1, 'of', chunks) spark.append(e.target.result) // Append array buffer currentChunk++ if (currentChunk < chunks) { loadNext() } else { let cur = +new Date() console.log('finished loading') // alert(spark.end() + '---' + (cur - pre)); // Compute hash let result = spark.end() resolve(result) } } fileReader.onerror = functio