前端vue大文件切片上传 代碼
时间: 2023-08-07 22:06:45 浏览: 41
以下是一个基本的前端Vue大文件切片上传的代码示例:
```
<template>
<div>
<input type="file" @change="selectFile">
<button @click="upload">上传</button>
<progress :value="progress" max="100"></progress>
</div>
</template>
<script>
export default {
data() {
return {
file: null, // 上传的文件
progress: 0, // 上传进度
chunkSize: 2 * 1024 * 1024, // 切片大小
currentChunk: 0, // 当前切片编号
totalChunks: 0, // 总切片数
uploadedChunks: 0, // 已上传的切片数
fileHash: null, // 文件哈希值
uploadUrl: '/api/upload' // 上传接口
}
},
methods: {
selectFile(event) {
this.file = event.target.files[0]
this.totalChunks = Math.ceil(this.file.size / this.chunkSize)
},
async upload() {
const fileReader = new FileReader()
fileReader.readAsArrayBuffer(this.file)
fileReader.onload = async () => {
const bytes = new Uint8Array(fileReader.result)
const chunkHashList = []
for (let i = 0; i < this.totalChunks; i++) {
const chunk = bytes.slice(i * this.chunkSize, (i + 1) * this.chunkSize)
const chunkHash = await this.calculateHash(chunk)
chunkHashList.push(chunkHash)
}
this.fileHash = await this.calculateHash(new Uint8Array(chunkHashList.join('').length))
this.uploadChunks(chunkHashList)
}
},
async uploadChunks(chunkHashList) {
for (let i = 0; i < this.totalChunks; i++) {
if (i === this.currentChunk) {
const chunk = this.file.slice(i * this.chunkSize, (i + 1) * this.chunkSize)
const formData = new FormData()
formData.append('file', chunk)
formData.append('hash', chunkHashList[i])
formData.append('filename', this.file.name)
formData.append('filehash', this.fileHash)
formData.append('chunksize', this.chunkSize)
formData.append('chunknumber', i + 1)
const response = await this.uploadChunk(formData)
if (response.data.status === 'success') {
this.uploadedChunks++
this.progress = Math.round(this.uploadedChunks / this.totalChunks * 100)
if (this.uploadedChunks < this.totalChunks) {
this.currentChunk++
this.uploadChunks(chunkHashList)
} else {
this.progress = 100
alert('上传成功')
}
} else {
alert('上传失败')
}
}
}
},
async uploadChunk(formData) {
return await axios.post(this.uploadUrl, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
},
async calculateHash(chunk) {
const buffer = await crypto.subtle.digest('SHA-256', chunk)
return Array.from(new Uint8Array(buffer)).map(b => b.toString(16).padStart(2, '0')).join('')
}
}
}
</script>
```
上述代码中,selectFile方法用于选择文件,upload方法用于上传文件。在upload方法中,首先使用FileReader对象读取文件内容,然后将文件切成固定大小的多个切片,并计算每个切片的哈希值和整个文件的哈希值。接下来,通过循环依次上传每个切片,上传完成后更新上传进度。上传过程中,如果遇到上传失败的情况,会提示上传失败。