分片上传与断点续传
效果
初始化
- npm i init
- npm i express
- npm i express-fileupload
- npm i axios
- npm i crypto-js
为何断点续传
- 浏览器对文件大小限制
- 上传失败后重新传送
- 中断传送后再次传送
实现思路
前端
- 拿到文件,对文件进行读取操作
function read(file){
const reader=new FileReader()
return new Promise(((resolve, reject) => {
reader.onload=function (){
resolve(reader.result)
}
reader.onerror=reject
reader.readAsBinaryString(file)
}))
}
- MD5加密
const hash=CryptoJS.MD5(content)
- 对文件进行分片操作
while (uploaded<size){
const chunk=file.slice(uploaded,uploaded+chunkSize,type)
const formData=new FormData()
formData.append('name',name)
formData.append('type',type)
formData.append('size',size)
formData.append('hash',hash)
formData.append('file',chunk)
formData.append('offset',uploaded)
formData.append('index',index)
axiosArr.push(formData)
index+=1
uploaded +=chunk.size
}
- 判断这个文件是否上传过(也就是上传到一半中止了)
const local=localStorage.getItem(hash)
- 从当前地方继续上传
const newDoneArr=[]
isDoneArr.map((item,index)=>{
if(item===0){
newDoneArr.push(axiosArr[index])
}
})
progress.max=newDoneArr.length-1
progress.value=0
multiRequest(newDoneArr,1)
- 开始上传,加入待上传队列中
function enqueue(queue=[],url){
const len=queue.push(url)
request(queue,url)
return len
}
- 请求成功,修改状态数据
const result=await axios.post('/api/upload',formData)
const i=urlsClone.indexOf(formData)
const hash=formData.get('hash')
localStorage.setItem(hash,i)
result[i]=formData
isDoneArr[i]=1
- 判定是否上传完成
function dequeue(queue=[],formData){
progress.value += 1
queue.splice(queue.indexOf(formData),1)
if(uls.length){
enqueue(queue,uls.shift())
}else {
if(isDoneArr.indexOf(0)===-1){
output.innerText='上传成功'
progress.value=urlsClone.length
localStorage.removeItem(formData.get('hash'))
}
}
}
后端
- 利用FS模块向文件中写入数据
- 先解析出文件名
const {
name, type, size, offset, hash,index} = req.body
- 写入文件
await appendFile(filename, file.data)