有不少同學(xué)在問vue上傳文件到阿里oss的問題蕾哟,我之前也遇到過覆积,現(xiàn)在給同學(xué)們分享一下我的方法
先說明一點,web端上傳的方式有3種:
1徐紧、JavaScript客戶端簽名直傳
2静檬、服務(wù)端簽名后直傳
3、服務(wù)端簽名直傳并設(shè)置上傳回調(diào)
我用的是第二種服務(wù)端簽名后直傳并级,上傳組件是餓了么的Upload 上傳拂檩。
1、服務(wù)端做簽名(這是后端干的嘲碧,如果您是純前端就忽略吧)
let now = new Date()
now = now.setMinutes(now.getMinutes() + config.ALIYUN.get('EXPIRATION')) // 這是您自己定的簽名有效時間(我這里是以分鐘為單位)
let expiration = new Date(now)
var policyText = {
'expiration': expiration, // 設(shè)置該Policy的失效時間稻励,超過這個失效時間之后,就沒有辦法通過這個policy上傳文件了
'conditions': [
['content-length-range', 0, config.ALIYUN.get('CONTENTLENGTHRANGE')] // 自定義設(shè)置上傳文件的大小限制
]
}
var accessid = config.ALIYUN.get('ACCESSKEY') // ACCESSKEY呀潭、SECRETKEY都是阿里云申請的
var accesskey = config.ALIYUN.get('SECRETKEY')
var policyBase64 = Base64.encode(JSON.stringify(policyText)) // 這之后的都是加密和簽名钉迷,Base64用的是js-base64包至非,CryptoJS用的是crypto-js包
var message = policyBase64
var bytes = CryptoJS.HmacSHA1(message, accesskey)
var signature = bytes.toString(CryptoJS.enc.Base64)
this.body = { // 這里就是返回數(shù)據(jù)了
policy: policyBase64,
OSSAccessKeyId: accessid,
signature: signature
}
2钠署、前端獲取簽名
現(xiàn)在剩下的就是前端的工作了,前端先從服務(wù)端獲取簽名荒椭,再上傳圖片谐鼎。
前端從服務(wù)端獲取數(shù)據(jù)的方式很多,比如ajax趣惠、superagent等狸棍,用自己熟悉的吧身害,這里就不說了。直接說說餓了么的上傳組件吧草戈。
<el-upload class="avatar-uploader" :action="uploadHost" accept="image/*" :show-file-list="false" :on-success="handleSuccess" :before-upload="beforeUpload" :data="ossParams">
</el-upload>
參數(shù)說明:
action:您創(chuàng)建oss的外網(wǎng)地址
accept:接受的文件類型
on-success:上傳成功的回調(diào)函數(shù)
before-upload:上傳前的回調(diào)函數(shù)塌鸯,可以在這里做文件大小驗證等
data:這里放您從服務(wù)端獲取到的簽名數(shù)據(jù)
核心代碼如下:
// data字段
ossParams: {
key: '', // key后面有用,先默認(rèn)設(shè)空字符串
success_action_status: '200', // 默認(rèn)200
}
// 從服務(wù)端獲取到簽名的處理
let r = await request.get(process.env.OSS_TOKEN)
Object.assign(this.ossParams, r.body)
// 生成隨機字符串
randomString() {
return (new Date % 9e6).toString(36) + Math.random().toString(36).substring(2, 7)
},
// 上傳成功的回調(diào)
handleSuccess(res, file) {
this.imageUrl = this.uploadHost + '/' + this.ossParams.key
console.info(this.imageUrl)
},
// 上傳之前的回調(diào)
beforeUpload(file) {
const isLt2M = file.size / 1024 / 1024 < 2
if (!isLt2M) {
this.$message.error('上傳頭像圖片大小不能超過 2MB!');
}
this.ossParams.key = `${this.type}/${this.randomString()}.${file.type.split('/').pop()}`
return isLt2M;
},