前端大文件上传分片/断点续传/并发控制实现
#前端 #大文件上传 #分片 #断点续传
const CHUNK_SIZE = 5 * 1024 * 1024
function createChunks(file: File) {
const chunks = []
let cur = 0
while (cur < file.size) {
chunks.push(
file.slice(cur, cur + CHUNK_SIZE)
)
cur += CHUNK_SIZE
}
return chunks
}
npm i spark-md5
import SparkMD5 from 'spark-md5'
async function calculateHash(file: File) {
return new Promise((resolve) => {
const spark = new SparkMD5.ArrayBuffer()
const reader = new FileReader()
reader.readAsArrayBuffer(file)
reader.onload = (e) => {
spark.append(e.target?.result as ArrayBuffer)
resolve(spark.end())
}
})
}
const formData = new FormData()
formData.append('chunk', chunk)
formData.append('hash', fileHash)
formData.append('index', index.toString())
await axios.post('/upload-chunk', formData)
async function asyncPool(limit, tasks) {
const pool = []
const results = []
for (const task of tasks) {
const p = task()
results.push(p)
if (limit <= tasks.length) {
const e = p.then(() => {
pool.splice(pool.indexOf(e), 1)
})
pool.push(e)
if (pool.length >= limit) {
await Promise.race(pool)
}
}
}
return Promise.all(results)
}
POST /check-file
传: hash
服务器返回:
{
"uploadedList": [0,1,2,3]
}
前端:跳过已上传 chunk
onUploadProgress中拿到loaded和total
simple-uploader.js/ali-oss
import OSS from 'ali-oss'
const client = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: 'xxx',
accessKeySecret: 'xxx',
bucket: 'test',
})
await client.multipartUpload(
file.name,
file,
{
parallel: 4,
partSize: 1024 * 1024,
progress(p) {
console.log(p)
},
}
)
上一篇
uni-app学习笔记
下一篇
Vue实现购物车