因为要跟后端交互,上传前要拿到文件的已上传信息,所以要给后端传MD5码,这个需要先计算出文件的MD5码,用 spark-md5 插件来计算
一、计算出文件的MD5值
要配合js的 FileReader 函数来使用 SparkMD5
import SparkMD5 from 'spark-md5'
// 计算MD5
getMD5(file, fileListID) {
// 使用sparkMD5的ArrayBuffer类,读取二进制文件
const spark = new SparkMD5.ArrayBuffer()
const fileReader = new FileReader()
// 异步操作,读完后的结果
fileReader.onload = (e) => {
// 把文件开始传入spark
spark.append(e.target.result)
// spark计算出MD5后的结果
const _md5 = spark.end()
console.log(_md5)
// 下面可以写一些自己需要的业务代码, 例如 fileItem.fileMD5 = _md5
}
// fileReader读取二进制文件
fileReader.readAsArrayBuffer(file)
},
二、把单个文件切分成小片上传
// 文件切片大小 2MB
chunkSize: 2097152,
// 文件总切片数
chunkTotal: Math.ceil(file.size / this.chunkSize),
// 分片上传 fileItem 是单个文件的对象信息,包含该file的分片大小等信息,可以通过后端查询结果赋值
// fileItem.currentChunk 是单个文件的当前要上传的分片序号,要上传第一片就是1
// fileItem.fileSize 是单个文件的总大小
// fileItem.fileMD5 是上面计算出来的MD5值
fragmentUpload(fileItem) {
// 批量循环发送分片上传请求
for (let i = fileItem.currentChunk; i <= fileItem.chunkTotal; i++) {
let start = i === 1 ? 0 : (i - 1) * this.chunkSize
let end = start + this.chunkSize >= fileItem.fileSize ? fileItem.fileSize : start + this.chunkSize
console.log('start:', start)
console.log('end:', end)
const chunkFile = fileItem.file.slice(start, end)
const _shardSize = end === fileItem.fileSize ? end - start : this.chunkSize
let formObj = new FormData()
// 这些都是调用你的后端接口需要的,不需要的可以删除
formObj.append('file', chunkFile)
formObj.append('name', fileItem.fileName)
formObj.append('type', fileItem.type)
formObj.append('hashCode', fileItem.fileMD5)
formObj.append('size', fileItem.fileSize)
formObj.append('shardIndex', _shardIndex.toString())
formObj.append('shardSize', _shardSize)
formObj.append('shardTotal', fileItem.chunkTotal)
// 调用上传接口,发送后端需要的数据
apiUploadFileByChunk(formObj).then((res) => {
if (res.status === '0') {
if (fileItem.currentChunk >= fileItem.chunkTotal) {
fileItem.progressNumber = 100
fileItem.status = '2'
this.countNumber++
this.startUpload()
} else {
fileItem.currentChunk++
fileItem.progressNumber = Math.floor(fileItem.currentChunk / fileItem.chunkTotal * 100)
}
} else {
fileItem.status = '3'
}
}).catch(() => {
fileItem.status = '3'
})
_shardIndex++
}
},