1.首先下载oss
执行:
npm install ali-oss
2.在项目中,配合element中upload组件使用,引入oss的js文件
import fileMixin from '@/mixins/file'
(已贴代码)
在upload组件的handleBeforeUpload中判断oss初始化是否成功
3.在handleHttpRequest中做上传判断
(saveOssResource后端接口 此处不贴代码了)
- 封装成单独的js代码 例如名为file.js 放入/mixins/file’ 代码如下
import {
checkOssClient,
initOssClient
} from '@/utils/upload'
import {
downloadFile
} from '@/utils/file'
// 下载的方法
const moment = require('moment')
let client = null
export default {
methods: {
async initAliOssClient() {
// 检查是否已有 Oss Client
client = checkOssClient()
if (!client) {
try {
await this.$api
.getResourceOssToken({})
.then((res) => {
const credentials = res.data
client = initOssClient(
credentials.accessKeyId,
credentials.accessSecret,
credentials.securityToken,
credentials.region,
credentials.bucket,
credentials.expiration,
)
})
} catch (error) {
this.$message.error(`${error}`)
return
}
}
return client
},
// 文件上传至 oss
async uploadFileToAliOss(opt, {
callback
}) {
// 获取文件后缀
const tmp = opt.file.name.split('.')
const extname = tmp.pop().toLowerCase()
const day = moment().format('YYYY-MM-DD')
// 生产随机文件名
const randomName = Array(32)
.fill(null)
.map(() => Math.round(Math.random() * 16).toString(16))
.join('')
const path = `/${extname}/${day}/${randomName}.${extname}`
let url
try {
let resourceName = opt.file.name
// 使用 multipartUpload 正式上传到 oss
const res = await client.multipartUpload(path, opt.file, {
progress: async function (p) {
// progress is generator
let e = {}
e.percent = p * 100
// 上传进度条,el-upload 组件自带的方法
opt.onProgress(e)
},
headers: {
'Content-Type': `application/octet-stream`,
'Content-Disposition': 'attachment;filename=' + encodeURIComponent(resourceName),
'x-oss-object-acl': 'public-read'
}
})
// 去除 oss 分片上传后返回所带的查询参数,否则访问会 403
const ossPath = res.res.requestUrls[0].split('?')[0]
// 替换协议,统一使用 'https://',否则 Android 无法显示图片
url = ossPath.replace('http://', 'https://')
} catch (error) {
console.log(error, 'error')
this.$message.error('文件上传失败或取消')
return
}
const {
size,
name,
uid
} = opt.file
callback({
url,
size,
name,
originPath: path.substring(path.indexOf('/') + 1, path.length),
uid,
})
},
// 下载文件
downloadFile(file) {
if (file?.oid) {
this.getFileDownloadInfo(file.oid, (fileUrl) => {
downloadFile({
url: fileUrl
})
})
}
},
// 获取文件下载信息
getFileDownloadInfo(oid, callback) {
this.$api
.getFileDownloadInfo({
oid
})
.then(response => {
const {
data
} = response
// 该文件的上传类型(阿里云oss 或 默认上传)不同
// 返回的文件下载也不同
// 可能是阿里云oss,也可能是默认上传ftp地址
if (data) callback(data)
})
.catch(error => {
console.log('getFileDownloadInfo error', error)
})
}
},
}
引用的oss方法,放入utils/upload中,代码如下
const OSS = require('ali-oss')
const moment = require('moment')
const env = process.env.NODE_ENV
let expirationTime = null // STS token 过期时间
let client = null // OSS Client 实例
const bucket = {
development: 'local-test-bucket-t',
dev: 'filesdev',
pre: 'filespre',
beta: 'filespro',
production: 'filespro'
}
// 初始化 oss client
export function initOssClient(accessKeyId, accessKeySecret, stsToken, region, bucket, expiration) {
client = new OSS({
accessKeyId,
accessKeySecret,
stsToken,
region,
bucket,
secure: true
})
expirationTime = expiration
return client
}
// 检查 oss 实例以及过期时间
export function checkOssClient() {
const current = moment()
return moment(expirationTime).diff(current) < 0 ? null : client
}
// 用于 sts token 失效、用户登出时注销 oss client
export function destroyOssClient() {
client = null
}