问题背景
最近上传视频的功能,突然炸了,两年没动的代码,突然不行辽,首次上传成功,后面继续上传就可以,但凡有一次上传失败,再上传文件就不行。
这里博主使用的是凭证上传方式哈。
凭证上传
官方文档:Web(JavaScript)上传SDK
查看了官方文档,确实是提到了,如使用1.5.3之前版本重新上传,请修改待上传文件名称,不要与上传中断的文件重名,避免报错。
项目使用的确实是1.5.0版本,所以我首先是把upload-sdk升级到了1.5.5
如果需要下载对应版本,可以看这里:Javascript上传SDK
upload-sdk升级之后,oss-sdk用的依然是6.8.0,这时候上传还是不行,首次上传可以成功,但是如果有重复名称的文件,再次上传,就会一直失败,报404
升级版本
询问了阿里云技术人员,被告知1.5.5对应的是6.17.1,所以又升级了oss-sdk。
更新了版本之后,如果是新文件,上传和续传没问题了,只是如果文件名字和之前的相同,上传会报403,续传会报404
这是缓存引起的,在new AliyunUpload.Vod({}) 的地方,新增个 localCheckpoint: true ,并且把本地存储清空,就可以了,或者也可以重命名文件。
代码
createUploader (i) {
let self = this
let uploader = new AliyunUpload.Vod({
timeout: 60000,
partSize: 1048576, // 分片大小默认1M,不能小于100K
parallel: 5, // 并行上传分片个数,默认5
retryCount: 3, // 网络原因失败时,重新上传次数,默认为3
retryDuration: 2, // 网络原因失败时,重新上传间隔时间,默认为2秒
region: "cn-shanghai", // 上传到点播的地域
userId: "190917894512121",
localCheckpoint: true,//此参数是禁用服务端缓存,不影响断点续传
// 开始上传
// 如果是 UploadAuth 上传方式, 需要调用 uploader.setUploadAuthAndAddress 方法
// 如果是 UploadAuth 上传方式, 需要根据 uploadInfo.videoId是否有值,调用点播的不同接口获取uploadauth和uploadAddress
// 如果 uploadInfo.videoId 有值,调用刷新视频上传凭证接口,否则调用创建视频上传凭证接口
// 如果 uploadInfo.videoId 存在, 调用 刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)
// 如果 uploadInfo.videoId 不存在,调用 获取视频上传地址和凭证接口(https://help.aliyun.com/document_detail/55407.html)
onUploadstarted: function (uploadInfo) {
if (!uploadInfo.videoId) {
uploadVideoAuthApi(self.vedioData[i]).then((res) => {
self.uploadDisabled = true
let { uploadAuth, uploadAddress, videoId } = res.data.operateCallBackObj;
uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId);
uploader.startUpload()
})
} else {
// 如果videoId有值,根据videoId刷新上传凭证
refreshUploadVideoAuthApi(uploadInfo.videoId).then(res => {
let {uploadAuth, uploadAddress, videoId} = res.data.operateCallBackObj
uploader.setUploadAuthAndAddress(uploadInfo, uploadAuth, uploadAddress, videoId)
uploader.startUpload()
})
}
},
// 文件上传成功
onUploadSucceed: function (uploadInfo) {
console.log("onUploadSucceed: " + uploadInfo.file.name + ", endpoint:" + uploadInfo.endpoint + ", bucket:" + uploadInfo.bucket + ", object:" + uploadInfo.object)
self.statusText = '文件上传成功!'
},
// 文件上传失败
onUploadFailed: function (uploadInfo, code, message) {
console.log("onUploadFailed: file:" + uploadInfo.file.name + ",code:" + code + ", message:" + message)
self.statusText = '文件上传失败!'
},
// 取消文件上传
onUploadCanceled: function (uploadInfo, code, message) {
console.log("Canceled file: " + uploadInfo.file.name + ", code: " + code + ", message:" + message)
self.statusText = '文件已暂停上传'
},
// 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
onUploadProgress: function (uploadInfo, totalSize, progress) {
console.log("onUploadProgress:file:" + uploadInfo.file.name + ", fileSize:" + totalSize + ", percent:" + Math.ceil(progress * 100) + "%")
let progressPercent = Math.ceil(progress * 100)
self.authProgress = progressPercent
self.statusText = '文件上传中...'
},
// 上传凭证超时
onUploadTokenExpired: function (uploadInfo) {
// 上传大文件超时, 如果是上传方式一即根据 UploadAuth 上传时
// 需要根据 uploadInfo.videoId 调用刷新视频上传凭证接口(https://help.aliyun.com/document_detail/55408.html)重新获取 UploadAuth
// 然后调用 resumeUploadWithAuth 方法, 这里是测试接口, 所以我直接获取了 UploadAuth
let refreshUrl = 'https://demo-vod.cn-shanghai.aliyuncs.com/voddemo/RefreshUploadVideo?BusinessType=vodai&TerminalType=pc&DeviceModel=iPhone9,2&UUID=59ECA-4193-4695-94DD-7E1247288&AppVersion=1.0.0&Title=haha1&FileName=xxx.mp4&VideoId=' + uploadInfo.videoId
axios.get(refreshUrl).then(({data}) => {
let uploadAuth = data.UploadAuth
uploader.resumeUploadWithAuth(uploadAuth)
console.log('upload expired and resume upload with uploadauth ' + uploadAuth)
})
self.statusText = '文件超时...'
},
// 全部文件上传结束
onUploadEnd: function (uploadInfo) {
console.log("onUploadEnd: uploaded all the files")
self.statusText = '文件上传完毕'
}
})
return uploader
}