前言:
網(wǎng)絡上許多的文章資料,全是使用阿里云官方的SDK,ali-oss插件去做直傳。可是各位素未謀面的朋友要注意,這個SDK它支持web環(huán)境使用,也就是PC端瀏覽器。
當項目環(huán)境切換到微信小程序,是無法使用這種方式的,當然官方也有給出微信小程序直傳的文檔,繼續(xù)往下看。
支持配置OSS直傳的callback參數(shù),這是其它文章中沒用到的
官方:如何使用ali-oss進行直傳https://help.aliyun.com/document_detail/64041.html?spm=a2c4g.383954.0.0.43c25e89vo4jkS
官方:微信小程序OSS直傳https://help.aliyun.com/document_detail/92883.html?spm=a2c4g.31925.0.0.24de344egXVqTI
代碼:
酒過三巡我還是少說話,多貼代碼。并且把一些踩坑的地方告訴大家。繼續(xù)往下看。
首先需要下載三個庫。
注意:官方文檔是讓我們使用import { Base64 } from 'js-base64';? ?
可是它會它會報錯?。?!根本用不了。
所以需要換成import base64 from 'base-64';import utf8 from 'utf8'
npm install?crypto-js --save
npm install?base-64 --save
npm install?utf8 --save
crypto-js:是阿里官方的簽名庫
base-64、utf8:是用來轉碼,配合crypto-js使用的
簽名不都是后端的事情嗎?沒錯大部分是后端。但是我在官方文檔看到客戶端也可以簽名,然后這么隨口一說。
我親愛的后端同事便說:客戶端(前端)也可以簽名,那就你自己簽名吧。
配置callback(可選,根據(jù)后端要求來決定是否需要)
為什么需要使用callback,這就是后端的騷操作。
他要我們把文件順利傳到OSS后,再讓OSS去請求他的接口。
他接口會去做一些業(yè)務邏輯,比如改文件的重命名。而callback則是配置,后端處理業(yè)務邏輯的接口地址、接請求參數(shù)。文章來源:http://www.zghlxwxcb.cn/news/detail-471907.html
直傳OSS配置callback是有格式要求的,并且微信小程序端、web端,callback的配置格式要求還不一樣。
這里可能是因為用戶們很少用到callback參數(shù),官方文檔寫得也不準確。
大家按照我代碼來,指定是沒問題的。文章來源地址http://www.zghlxwxcb.cn/news/detail-471907.html
import crypto from 'crypto-js'
import base64 from 'base-64'
import utf8 from 'utf8'
<script>
methods: {
chooseAvatarEvent(event) {
const { avatarUrl } = event.detail
this.getFormDataParams().then(() => {
this.uploadFile(avatarUrl, 'tmp/', e => {})
})
},
// 計算簽名。
computeSignature(accessKeySecret, canonicalString) {
console.log(crypto.enc)
return crypto.enc.Base64.stringify(crypto.HmacSHA1(canonicalString, accessKeySecret))
},
getPolicyBase64() {
const date = new Date()
date.setHours(date.getHours() + 1)
const policyText = {
expiration: date.toISOString(), // 設置policy過期時間。
conditions: [
// 限制上傳大小。
['content-length-range', 0, 1024 * 1024 * 1024],
],
}
return policyText
},
async getFormDataParams() {
// 獲取STS臨時token,這是后端接口做的,找親愛的后端
const credentials = await queryOssGetStsToken()
const policyText = this.getPolicyBase64()
const uft8Str = utf8.encode(JSON.stringify(policyText))
const policy = base64.encode(uft8Str)
const signature = this.computeSignature(credentials.AccessKeySecret, policy)
const user_id = this.userInfo.user_id
const callback = {
// 設置回調請求的服務器地址,且要求必須為公網(wǎng)地址。
// 后端的接口地址:https://www.baidu.com/api/xxxx
callbackUrl: credentials.callbackUrl,
// 設置回調請求消息頭中Host的值,即您的服務器配置的Host值。
// host: 'yourHost',
// 設置發(fā)起回調時請求body的值。
callbackBody: 'bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}&type=avatar&user_id=' +
user_id,
// 設置發(fā)起回調請求的Content-Type。
callbackBodyType: 'application/x-www-form-urlencoded',
}
const uft8Str_callback = utf8.encode(JSON.stringify(callback))
const base64_callback = base64.encode(uft8Str_callback)
const formData = {
OSSAccessKeyId: credentials.AccessKeyId,
signature,
policy,
'success_action_status': '200',
'x-oss-security-token': credentials.SecurityToken,
callback: base64_callback,
}
this.formData = formData
console.log('formData===', this.formData)
},
uploadFile(filePath, dir, successc, failc) {
const _this = this
// 獲取上傳的文件類型
let fileTypeIndex = filePath.lastIndexOf('.')
let fileType = filePath.substring(fileTypeIndex)
//圖片名字 可以自行定義, 這里是采用當前的時間戳 + 150內的隨機數(shù)來給圖片命名的
// const aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + '.png';
const aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + fileType
uni.uploadFile({
// 注意:阿里云OSS的訪問地址,并不是接口請求域名
url: 'http://pxxxxx-xxxx-xxx.oss-cn-shenzhen.aliyuncs.com', //阿里云OSS訪問地址
filePath: filePath, //要上傳文件資源的路徑
name: 'file', //必須填file
formData: {
'key': aliyunFileKey,
...this.formData
},
callback: this.formData.callback,
success: function(res) {
const resObj = JSON.parse(res.data)
_this.userInfo.avatar_id = resObj.data.id
_this.userInfo.avatar = resObj.data.url
console.log('上傳成功===', resObj)
},
fail: function(err) {
// err.wxaddinfo = aliyunServerURL
// failc(err)
},
})
}
}
</script>
<template>
<view class="item-panel flex-1">
<u-image :src="userInfo.avatar" width="80rpx" height="80rpx" shape="circle"></u-image>
<button class="upload-box" open-type="chooseAvatar" @chooseavatar="chooseAvatarEvent"></button>
<view class="ml-20 flex ai-center">
<u-icon name="arrow-right"></u-icon>
</view>
</view>
</template>
<style lang="scss" scoped>
.item-panel {
display: flex;
position: relative;
.upload-box {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
right: 0;
top: 0;
}
}
</style>
到了這里,關于前端阿里云OSS直傳,微信小程序版本的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!