前言
视频文件过大,上传时间太久,容易让人以为卡住了。因此采用切割文件的形式上传,当然这里仅仅是前端的el-upload的手动上传,后端需要拼接数据,然后保存数据库,返回文件路径
使用步骤
代码如下:
// 手动上传
async uploadFile({ data, file }) {
// console.log(file)
this.uploading = false;
if (file.size / 1024 / 1024 < 10) {
// 低于10m不分片
this.loading = true
// 这是进度条,简单的写一个lodding页组件
this.percentage = 90
let formData = new FormData()
formData.append('file', file)
this.$http.post(this.uploadUrl, formData).then(res => {
this.loading = false
let fileData = res.result;
if (JSON.stringify(this.fileList).indexOf(JSON.stringify(fileData)) == -1) {
this.fileList.push(fileData);
}
this.$message.success('文件上传成功!');
})
} else {
// 低于10m不分片
// 分片大小
const chunkSize = 10 * 1024 * 1024
// 分片数量
const totalChunks = Math.ceil(file.size / chunkSize)
// 分片id
let identifier = new Date().getTime() + ((Math.random() * 999) | 0)
// 分片请求
const readChunk = (index => {
let start = (index - 1) * chunkSize
let end = Math.min(file.size, start + chunkSize)
// 分片文件
let chunk = file.slice(start, end)
// 请求参数
let formData = new FormData()
formData.set('chunkNumber', index)
formData.set('chunkSize', chunkSize)
formData.set('totalChunks', totalChunks)
formData.set('identifier', identifier)
formData.set('file', chunk)
formData.set('fileName', file.name)
// 发请求
return uploadChunk(formData, index)
})
// 接口请求
const uploadChunk = (formData, idx) => {
return new Promise((resolve, reject) => {
this.$http.post(this.uploadF, formData).then(res => {
if (res.code == 407) {
// 上传失败,重新上传chunkNumber、identifier不需要变
uploadChunk(formData, idx)
} else if (res.code == 200) {
// 上传成功
// 进度条
this.percentage = idx * parseInt(100 / totalChunks)
if (idx == totalChunks) {
// 上传结束之后关闭遮盖层且回显数据
let fileData = res.result
if (JSON.stringify(this.fileList).indexOf(JSON.stringify(fileData)) == -1) {
this.fileList.push(fileData);
this.loading = false
}
this.$message.success('文件上传成功!');
}
return resolve(res)
} else if (res.code == 500) {
// 上传失败,重新上传
this.loading = false
this.$message.success('文件上传失败,请重新上传!');
}
}).catch(err => {
console.log(err)
this.loading = false
return reject(err)
})
})
}
// 遍历分片数量
for (let i = 1; i < totalChunks + 1; i++) {
// 启动遮盖层
this.loading = true
// 依次发请求
await readChunk(i)
}
// 这是不需要依次发请求的
// const promiseList = []
// for (let i = 1; i < totalChunks + 1; i++) {
// this.loading = true
// promiseList.push(readChunk(i))
// }
// let tt = await Promise.all(promiseList)
// let fileData = tt.filter(i => i.result.id)[0].result
// if (JSON.stringify(this.fileList).indexOf(JSON.stringify(fileData)) == -1) {
// this.fileList.push(fileData);
// this.loading = false
// }
// this.$message.success('文件上传成功!');
}
}