// 通过文件流来判定类型
async blobToString(blob){
return new Promise(resolve=>{
const reader = new FileReader()
reader.onload = function(){
console.log(reader.result)
const ret = reader.result.split('')
.map(v=>v.charCodeAt())
.map(v=>v.toString(16).toUpperCase())
// .map(v=>v.padStart(2,'0'))
.join('')
resolve(ret)
// const ret = reader.
}
reader.readAsBinaryString(blob)
})
} ,
// 判定是不是gif
async isGif(file){
// GIF89a 和GIF87a
// 前面6个16进制,'47 49 46 38 39 61' '47 49 46 38 37 61'
// 16进制的转换
const ret = await this.blobToString(file.slice(0,6))
const isGif = (ret=='47 49 46 38 39 61') || (ret=='47 49 46 38 37 61')
return isGif
},
async isPng(file){
const ret = await this.blobToString(file.slice(0,8))
const ispng = (ret == "89 50 4E 47 0D 0A 1A 0A")
return ispng
},
async isJpg(file){
const len = file.size
const start = await this.blobToString(file.slice(0,2))
const tail = await this.blobToString(file.slice(-2,len))
const isjpg = (start=='FF D8') && (tail=='FF D9')
return isjpg
},
async isImage(file){
return await this.isGif(file) || await this.isPng(file)
},
//文件切片 file.slice(1000,2000);字节
createFileChunk(file,size=CHUNK_SIZE){
const chunks = []
let cur = 0
while(cur<this.file.size){
chunks.push({index:cur, file:this.file.slice(cur,cur+size)})
cur+=size
}
return chunks
},
//计算文件的MD5值
async calculateHashWorker(){
return new Promise(resolve=>{
this.worker = new Worker('/hash.js')
this.worker.postMessage({chunks:this.chunks})
this.worker.onmessage = e=>{
const {progress,hash} = e.data
this.hashProgress = Number(progress.toFixed(2))
if(hash){
resolve(hash)
}
}
})
},
async uploadChunks(uploadedList=[]){
const requests = this.chunks.filter(chunk=>uploadedList.indexOf(chunk.name)==-1)
.map((chunk,index)=>{
// 转成promise const form = new FormData()
form.append('chunk',chunk.chunk)
form.append('hash',chunk.hash)
form.append('name',chunk.name)
// form.append('index',chunk.index)
return {form, index:chunk.index,error:0}
})
.map(({form,index})=> this.$http.post('/uploadfile',form,{
onUploadProgress:progress=>{
// 不是整体的进度条了,而是每个区块有自己的进度条,整体的进度条需要计算
this.chunks[index].progress = Number(((progress.loaded/progress.total)*100).toFixed(2))
}
}
))
通过Blob.slice方法,可以将大文件分片,轮循向后台提交各文件片段,即可实现文件的分片上传。