首先引入静态文件:
华为云官网提供js下载的链接
然后后端提供一个公用接口,返回华为云上传的基本配置:
官网提供的链接:华为云obs信息配置
一:单个上传
huaweiyunUpload (file, fileName, name, url, size, callback, failCallBack) {
// huaweiyunConfig为上面接口存储的vuex数据
// 华为云上传流程
var _self = this
var obsClient = new ObsClient({ // 创建ObsClient实例
access_key_id: _self.huaweiyunConfig.accessKeyId,
secret_access_key: _self.huaweiyunConfig.secretAccessKey,
// 这里以华北-北京四为例,其他地区请按实际情况填写
server: _self.huaweiyunConfig.endPoint
})
var progressRate = function (transferredAmount, totalAmount, totalSeconds) {
// 获取上传平均速率(KB/S)
console.log(transferredAmount * 1.0 / totalSeconds / 1024)
// 获取上传进度百分比
_self.$set(_self, 'percent', Math.floor(transferredAmount * 100.0 / totalAmount))
}
obsClient.putObject({
Bucket: _self.huaweiyunConfig.bucketName,
Key: this.huaweiyunConfig.prefix+fileName,
SourceFile: file.file,
ProgressCallback: progressRate
}, function (err, result) {
if (err) {
console.error('Error-->' + err)
if (failCallBack) failCallBack(err)
} else {
if (result.CommonMsg.Status == 200) {
// console.log('success====', result)
if (callback) callback({ name: fileName, fileName: name, url: url, size: size })
}
}
})
}
页面应用:
const url = this.huaweiyunConfig.viewPath + this.huaweiyunConfig.prefix+fileName
// file 文件流 fileName带后缀的文件名 name不带后缀的文件名 url 文件存储路径 size 文件大小
this.huaweiyunUpload(file, fileName, name, url, size, ()=>{// success function }, ()=>{// fail function})
二:分段上传
createInitTask (file, fileUrl = '', sucCallBack, failCallBack) { // 大文件上传-分段上传
var _self = this
const fileName = file.file.name // 文件名-带后缀
const routeName = this.$route.matched[0].path
const fileFullUrl = this.huaweiyunConfig.prefix + routeName + '/' + fileUrl + new Date().getTime() + '/' + fileName
// 创建ObsClient实例
var obsClient = new ObsClient({
access_key_id: _self.huaweiyunConfig.accessKeyId,
secret_access_key: _self.huaweiyunConfig.secretAccessKey,
// 这里以华北-北京四为例,其他地区请按实际情况填写
server: _self.huaweiyunConfig.endPoint
})
obsClient.initiateMultipartUpload({
Bucket: _self.huaweiyunConfig.bucketName,
Key: fileFullUrl,
ContentType: 'text/plain',
Metadata: { property: 'property-value' }
}, function (err, result) {
if (err) {
if (failCallBack) failCallBack()
} else {
console.log('Status-->' + result.CommonMsg.Status)
if (result.CommonMsg.Status < 300 && result.InterfaceResult) {
console.log('UploadId-->' + result.InterfaceResult.UploadId)
// if (createSuc) createSuc(obsClient,result, file, fileFullUrl)
_self.uploadSection(obsClient, result, file, fileFullUrl, sucCallBack, failCallBack)
}
}
})
},
uploadSection (obsClient, result, file, fileFullUrl, sucCallBack, failCallBack) { // 上传段
var _self = this
const PartSize = 20 * 1024 * 1024
const UploadId = result.InterfaceResult.UploadId
// const file = document.getElementById('input-file').files[0];
const lastPartSize = file.file.size % PartSize
// 段数量
const count = Math.ceil(file.file.size / PartSize)
let start = 1 // 当前段值
const Parts = [] // 存放PartNumber, ETag
// 上传第n段
const uploadPart = (n, callback) => {
obsClient.uploadPart({
Bucket: _self.huaweiyunConfig.bucketName,
Key: fileFullUrl,
// 设置分段号,范围是1~10000
PartNumber: n,
// 设置Upload ID
UploadId,
// 设置将要上传的大文件
SourceFile: file.file,
// 设置分段大小
PartSize: count === n ? lastPartSize : PartSize,
// 设置分段的起始偏移大小
Offset: (n - 1) * PartSize
}, function (err, result) {
if (err) {
console.log('Error-->' + err)
if (failCallBack) failCallBack()
} else {
console.log('Status-->' + result.CommonMsg.Status)
if (result.CommonMsg.Status < 300 && result.InterfaceResult) {
// console.log('ETag-->' + result.InterfaceResult.ETag);
Parts.push({ PartNumber: n, ETag: result.InterfaceResult.ETag })
start++
if (start <= count) uploadPart(start)
if (callback) callback()
if (n === count) { // 最后一段
_self.mergeSection(obsClient, UploadId, Parts, fileFullUrl, file, sucCallBack, failCallBack)
}
}
}
})
}
// 上传段
uploadPart(start)
},
mergeSection (obsClient, UploadId, Parts, fileFullUrl, file, sucCallBack, failCallBack) { // 合并段
var _self = this
let fileName = file.file.name // 文件名-带后缀
const size = file.file.size // 文件大小 B
var index = fileName.lastIndexOf('/')
fileName = fileName.substring(
index + 1,
fileName.length
)
const arr = fileName.split('.')
arr && arr.splice(arr.length - 1, 1)
const name = arr && arr.join('.') // 文件名-不带后缀
const url = this.huaweiyunConfig.viewPath + fileFullUrl // 完整url
obsClient.completeMultipartUpload({
Bucket: _self.huaweiyunConfig.bucketName,
Key: fileFullUrl,
// 设置Upload ID
UploadId: UploadId,
Parts: Parts
}, function (err, result) {
if (err) {
console.log('Error-->' + err)
if (failCallBack) failCallBack()
} else {
// console.log('Status-->' + result.CommonMsg.Status)
if (sucCallBack) sucCallBack({ name: fileName, fileName: name, url: url, size: size })
}
})
}
页面应用:
this.createInitTask(file, fileFullUrl, (obj) => {
that.fileList = []
that.fileList.push({ name: obj.fileName, appendixName: obj.name, appendixUrl: obj.url, size: obj.size })
that.batchUploadWorkFilesAjax(that.fileList)
}, () => { that.btnLoading = false })