微信小程式 上傳圖片至阿里雲OSS(支援多圖片上傳)
我們先講下為什麼要把圖片檔案上傳到雲伺服器呢, 有什麼好處呢?
1、能減輕我們自己伺服器的頻寬
如果一個程式裡有多處地方用到使用者上傳圖片等功能的話,建議還是放到阿里雲或者千牛雲等其他平臺上來儲存我們的圖片,可以給公司的伺服器減少很多壓力,磁碟儲存也就不會太大
2、提升使用者體驗感
我們開發的產品一般都是以使用者體驗感為主對吧?
當用戶在使用我們的小程式上傳圖片時,如果一次上傳了多張,我們的伺服器介面肯定是要進行對這些上傳檔案進行處理,如果同一時間訪問量大的話,我們的程式先處理這些請求,在把圖片存放到某個檔案裡,再返回給客服端結果,處理的相對是比較慢的,使用者等待的時間也就比較長,體驗感不好。
如果換成上傳圖片到雲伺服器上,我們就可以直接把這個外網可訪問的圖片地址在前端拿到,然後後端接收在存入資料庫,最後再返回結果就好,處理的時間就大大的減少了
接下來切入主題,先看下目錄結構,也就是我們小程式需要用到的檔案如下:
config.js:配置檔案,程式碼如下:
var fileHost = "https://xxx/";//你的阿里雲OSS地址 在你當前小程式的公眾號後臺的uploadFile 合法域名也要配上這個域名 var config = { uploadImageUrl: `${fileHost}`, // 預設存在根目錄,可根據需求改 AccessKeySecret: 'xxx', // AccessKeySecret 去你的阿里雲上控制檯上找 OSSAccessKeyId: 'xxx', // AccessKeyId 去你的阿里雲上控制檯上找 timeout: 80000 //這個是上傳檔案時Policy的失效時間 }; module.exports = config
fileHost:把 xxx 替換成你的阿里雲oss地址
AccessKeyId和AccessKeySecret怎麼拿到?
可以百度搜下或者看下阿里雲的幫助文件 地址:https://helpcdn.aliyun.com/knowledge_detail/48699.html
uploadFile.js:主要的業務邏輯實現過程,程式碼如下:
const env = require('config.js'); //配置檔案,在這檔案裡配置你的OSS keyId和KeySecret,timeout:87600; const base64 = require('base64.js');//Base64,hmac,sha1,crypto相關演算法 require('hmac.js'); require('sha1.js'); const Crypto = require('crypto.js'); /* *上傳檔案到阿里雲oss *@param - filePath :圖片的本地資源路徑 *@param - dir:表示要傳到哪個目錄下 *@param - successc:成功回撥 *@param - failc:失敗回撥 */ const uploadFile = function (filePath, dir, successc, failc) { if (!filePath || filePath.length < 9) { wx.showModal({ title: '圖片錯誤', content: '請重試', showCancel: false, }) return; } console.log('上傳圖片.....'); //圖片名字 可以自行定義, 這裡是採用當前的時間戳 + 150內的隨機數來給圖片命名的 const aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + '.png'; const aliyunServerURL = env.uploadImageUrl;//OSS地址,需要https const accessid = env.OSSAccessKeyId; const policyBase64 = getPolicyBase64(); const signature = getSignature(policyBase64);//獲取簽名 wx.uploadFile({ url: aliyunServerURL,//開發者伺服器 url filePath: filePath,//要上傳檔案資源的路徑 name: 'file',//必須填file formData: { 'key': aliyunFileKey, 'policy': policyBase64, 'OSSAccessKeyId': accessid, 'signature': signature, 'success_action_status': '200', }, success: function (res) { if (res.statusCode != 200) { failc(new Error('上傳錯誤:' + JSON.stringify(res))) return; } successc(aliyunServerURL + aliyunFileKey); }, fail: function (err) { err.wxaddinfo = aliyunServerURL; failc(err); }, }) } const getPolicyBase64 = function () { let date = new Date(); date.setHours(date.getHours() + env.timeout); let srcT = date.toISOString(); const policyText = { "expiration": srcT, //設定該Policy的失效時間,超過這個失效時間之後,就沒有辦法通過這個policy上傳檔案了 "conditions": [ ["content-length-range", 0, 5 * 1024 * 1024] // 設定上傳檔案的大小限制,5mb ] }; const policyBase64 = base64.encode(JSON.stringify(policyText)); return policyBase64; } const getSignature = function (policyBase64) { const accesskey = env.AccessKeySecret; const bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, { asBytes: true }); const signature = Crypto.util.bytesToBase64(bytes); return signature; } module.exports = uploadFile;
註釋都寫在檔案裡頭了,你們慢慢看哈!
主要說下圖片的命名,我是採用時間戳 + 隨機數的方式和字尾為.png格式的圖片檔案;
你們可以替換成你自己想要的格式; 可以把上面的這句話 從 new Date() 開始往後進行修改
其他的檔案都是一些演算法檔案,我都打包了,最後再給們原始檔的地址連結 0.0
如何使用?
在你需要用的頁面上,比如我們index.wxml裡有個按鈕如下:
<button type='primary' bindtap='choose'>選擇照片</button>
在index.js檔案裡引入:
//index.js
//獲取應用例項
const app = getApp()
var uploadImage = require('../../utils/uploadFile.js');//地址換成你自己存放檔案的位置
var util = require('../../utils/util.js');
Page({
data: {
},
//選擇照片
choose: function () {
wx.chooseImage({
count: 9, // 預設最多一次選擇9張圖
sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,預設二者都有
sourceType: ['album', 'camera'], // 可以指定來源是相簿還是相機,預設二者都有
success: function (res) {
// 返回選定照片的本地檔案路徑列表,tempFilePath可以作為img標籤的src屬性顯示圖片
var tempFilePaths = res.tempFilePaths;
var nowTime = util.formatTime(new Date());
//支援多圖上傳
for (var i = 0; i < res.tempFilePaths.length; i++) {
//顯示訊息提示框
wx.showLoading({
title: '上傳中' + (i + 1) + '/' + res.tempFilePaths.length,
mask: true
})
//上傳圖片
//你的域名下的/cbb檔案下的/當前年月日檔案下的/圖片.png
//圖片路徑可自行修改
uploadImage(res.tempFilePaths[i], 'images/' + nowTime + '/',
function (result) {
console.log("======上傳成功圖片地址為:", result);
//做你具體的業務邏輯操作
wx.hideLoading();
}, function (result) {
console.log("======上傳失敗======", result);
//做你具體的業務邏輯操作
wx.hideLoading()
}
)
}
}
})
}
})
以上是可以支援多圖上傳的,傳一張也是可以的; 上傳圖片後具體存放在哪的位置可自行定義!
好了,上傳成功拿到圖片地址,就可以為所欲為的做你想做的事了~~
最後貼下我這專案的GitHub地址,所有的檔案都在這: