vue实现大文件上传
大文件上传的实现思路
大文件上传通常涉及分片上传、断点续传和文件校验等关键技术。Vue作为前端框架,需结合后端API实现完整流程。
前端分片上传实现
使用File对象的slice方法将文件切割为多个小块,每块单独上传:
// 文件分片函数
function createFileChunks(file, chunkSize = 5 * 1024 * 1024) {
const chunks = []
let cur = 0
while (cur < file.size) {
chunks.push(file.slice(cur, cur + chunkSize))
cur += chunkSize
}
return chunks
}
上传进度跟踪
通过axios的onUploadProgress事件监听上传进度:
axios.post('/upload', formData, {
onUploadProgress: progressEvent => {
const percent = Math.round(
(progressEvent.loaded / progressEvent.total) * 100
)
console.log(`上传进度: ${percent}%`)
}
})
断点续传实现
前端需要记录已上传的分片信息,通常使用localStorage或服务端返回的记录:

// 检查已上传分片
async function checkUploadedChunks(fileHash) {
const { data } = await axios.get('/check-upload', {
params: { fileHash }
})
return data.uploadedChunks || []
}
文件完整性校验
上传完成后需要发送文件hash进行最终校验:
// 生成文件hash(使用spark-md5库)
function generateFileHash(file) {
return new Promise(resolve => {
const spark = new SparkMD5.ArrayBuffer()
const reader = new FileReader()
reader.onload = e => {
spark.append(e.target.result)
resolve(spark.end())
}
reader.readAsArrayBuffer(file)
})
}
完整上传流程示例
async function uploadLargeFile(file) {
const fileHash = await generateFileHash(file)
const chunks = createFileChunks(file)
const uploadedChunks = await checkUploadedChunks(fileHash)
for (let i = 0; i < chunks.length; i++) {
if (uploadedChunks.includes(i)) continue
const formData = new FormData()
formData.append('chunk', chunks[i])
formData.append('hash', fileHash)
formData.append('index', i)
await axios.post('/upload-chunk', formData, {
onUploadProgress: e => updateProgress(i, e)
})
}
await axios.post('/merge', {
fileName: file.name,
fileHash,
chunkCount: chunks.length
})
}
后端接口设计要求
后端需要实现三个核心接口:

/check-upload:检查已上传分片/upload-chunk:接收单个分片/merge:合并所有分片
性能优化建议
使用Web Worker计算文件hash避免界面卡顿:
// worker.js
self.importScripts('spark-md5.min.js')
self.onmessage = function(e) {
const spark = new self.SparkMD5.ArrayBuffer()
const file = e.data
const reader = new FileReader()
reader.onload = function(e) {
spark.append(e.target.result)
self.postMessage(spark.end())
}
reader.readAsArrayBuffer(file)
}
错误处理机制
实现上传失败自动重试机制:
async function uploadWithRetry(formData, retries = 3) {
try {
return await axios.post('/upload-chunk', formData)
} catch (error) {
if (retries <= 0) throw error
return uploadWithRetry(formData, retries - 1)
}
}
界面展示优化
使用Element UI的Progress组件展示上传进度:
<el-progress
:percentage="uploadPercent"
:status="uploadStatus"
/>
注意事项
- 分片大小建议2-5MB,过小会增加请求次数,过大可能触发超时
- 文件hash生成比较耗时,务必使用Web Worker
- 清理上传失败的临时文件
- 考虑添加上传暂停/继续功能
- 对敏感文件进行内容安全检查






