跳到主要内容

upload 实现分片上传

什么是分片上传

在一些企业内部的 oa 或者中台系统中,经常会遇到文件上传的需求,当上传文件过大时,就需要使用分片上传 ,前端把一个文件分成多个小块,然后一块一块的进行上传,最后服务端对文件进行整合,并且返回文件链接。

分片上传的优势在于

  • 上传速度快
  • 不会因为网络问题导致上传失败
  • 可以断点续传
  • 可以并发上传

原理

获取文件 md5

这一步在任何文件上传下载的场景中都非常常见以及重要,首先是 md5 值可以作为文件的唯一识别指纹,能够判断上传前后文件是否发生篡改和损坏,同时也能判断文件是否已经上传过,尽管 md5 值存在碰撞的风险,但是概率非常小,常规使用场景安全性已经足够,如果需要更安全,可以考虑使用 sha256。 通常我会使用 crypto-js 这个库来获取文件的 md5 值,当然 spark-md5 也值得推荐 。

import CryptoJS from "crypto-js";

const getMD5 = (file: File): Promise<string> => {
// 使用CryptoJS 获取文件md5值
const md5 = CryptoJS.MD5(file).toString()
return md5
}

文件切片

配置每片的大小,然后使用 slice 方法进行切片,最后返回一个包含所有切片的数组。 file 类型本身自带了 slice 方法,所以我们可以直接使用。

const config = {
...
bufferSize: 1024 * 1024 * 5, // 5MB
...
}

const getBlocks = (file: File) => {
const blocks = []

let endByte = 0
let startByte = 0
while (true) {
startByte = endByte
if (endByte + config.bufferSize >= file.size) {
endByte = file.size
} else {
endByte = endByte + config.bufferSize
}
const block = file.slice(startByte, endByte)
blocks.push(block)
if (endByte >= file.size) break
}
return blocks
}

上传文件分片

上传分片我们只需要按照循序上传即可

async function uploadBlocks(blocks) {
for (const block of blocks) {
await uploadBlock(block)
}
}

试一试