加载中...

计算文件MD5值实现文件秒传

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情

日常开发过程中,经常会遇到需要上传文件的问题,有时候文件会特别的大,这时候需要考虑文件秒传文件分片上传。 以此来实现高效上传,提升用户体验。本文主要介绍文件秒传。

文件秒传原理

文件秒传的原理是在前端上传文件之前,拿到文件,并计算文件的MD5值,请求接口将MD5传递给后端,后端查询数据库是否存在相同的MD5值,如果存在,则直接返回对应的文件ID, 如果不存在,则返回空。

前端在收到响应后,如果文件id存在,则直接停止上传,将上传结果置为成功(秒传成功)。如果不存在,则走后续分片上传的流程。

常用组件

秒传关键在于计算文件MD5值,前端计算文件MD5值的常用工具为 spark-md5 它能够非常快速的计算大文件的MD5值, 满足开发需求。

函数封装

考虑到代码公用性,将此特抽出一个公用方法。 如下: 详见代码及注释。

js
复制代码
import SparkMD5 from ''spark-md5''; /** * 计算文件Md5 * 将文件分片逐步计算最终合并得出整个文件md5, 提升计算速度 * @param {*} file */ export default function computeFileMD5(file) { return new Promise((resolve, reject) => { let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice; let chunkSize = 2097152; // 按照一片 2MB 分片 let chunks = Math.ceil(file.size / chunkSize); // 片数 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); currentChunk++; if (currentChunk < chunks) { loadNext(); } else { console.log(''finished loading''); let md5 = spark.end(); //最终md5值 spark.destroy(); //释放缓存 resolve(md5); } }; fileReader.onerror = function (e) { console.warn(''oops, something went wrong.''); reject(e); }; function loadNext() { let start = currentChunk * chunkSize, let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize; fileReader.readAsArrayBuffer(blobSlice.call(file, start, end)); } loadNext(); }) }

函数的调用

函数调用一般在文件上传前置函数,注意异步

js
复制代码
async fileAdd(file) { // 注意此处file, file || file.file let md5 = await computeFileMD5(file.file); console.log(md5); // 调用接口实现秒传逻辑 }

总结

本文介绍了文件秒传的原理以及实现思路,其中对关键步骤获取md5做出了详细说明,以及示例了对应函数的封装和调用。希望可以帮助给有相关需求的人一些思路。