oss服务在视频文件上传的前端应用(关键点:1.oss服务协议,2.文件太大需要切片分段上传 3.oss服务与普通请求会有不同,返回在请求体里面。关键点是position)
<template>
<div class="upload-trunk-file">
<a-upload
class="upload"
action=""
:accept="acceptType"
:showUploadList = "false"
:beforeUpload="beforeUpload"
:customRequest="uploadRequest"
>
</template>
<script>
// import {globalBus} from '@/config/general/constant'
export default {
data() {
return {
blockSize: Number(this.trunkSize) * 1024 * 1024,
uploadFiles: []
}
},
methods: {
getFileParamsByUid(uid) {
return this.uploadFiles.find(item => item.uid === uid)
},
async trunkUpload(uid) {
let target = this.getFileParamsByUid(uid)
// 上传之前需要获取上传服务地址
if (!target.actionUrl) {
this.setUploadStatus(uid, 'waiting')
const {url} = await this.$https.get('/rims/service/oss/upload')
target.actionUrl = url
}
let {chunkNumber, totalChunks, status, file} = this.setUploadStatus(uid, 'uploading')
// 大于最小块,分段上传
while ((totalChunks >= chunkNumber && status === 'uploading')) {
const {blockSize} = this
const nextSize = Math.min(chunkNumber * blockSize, file.size)
const slice = file.slice((chunkNumber - 1) * blockSize, nextSize)
await this.uploadToOSS(slice, uid)
const cru = this.getFileParamsByUid(uid)
chunkNumber = cru.chunkNumber
totalChunks = cru.totalChunks
status = cru.status
}
},
// 上传OSS服务,并携带token信息
uploadToOSS(trunk, uid) {
const vm = this
let target = this.getFileParamsByUid(uid)
const CancelToken = this.$https.axios.CancelToken
const {path, position, chunkNumber, totalChunks, file, actionUrl} = target
const formData = new FormData()
formData.append('name', file.name)
formData.append('chunk', chunkNumber)
formData.append('chunks', totalChunks)
formData.append('file', trunk)
return this.$https.post(`${actionUrl}/webupload/1.0/${encodeURIComponent(file.name)}?token=${this._token}`, formData, {
headers: {
'Content-Type': 'multipart/form-data',
'x-dss-object-uri': path,
'x-dss-object-position': position
},
responseType: '',
timeout: 30000,
showErrorMessage: false,
cancelToken: new CancelToken((c) => {
target.cancelToken = c
})
}).then((res) => {
const info = this.formatResponeHeader(res)
const {errcode} = info
// errcode === 0 表示成功
if (errcode === '0') {
vm.onSuccess(uid, info)
return Promise.resolve(target)
} else {
vm.onError(uid, res)
// vm.setUploadStatus(uid, 'error')
return Promise.reject(target)
}
}).catch((e) => {
vm.onError(uid, e)
return Promise.reject(e)
})
},
</script>