1. 程式人生 > >微信小程式 上傳圖片至阿里雲OSS(支援多圖片上傳)

微信小程式 上傳圖片至阿里雲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地址,所有的檔案都在這:

https://github.com/hujinchen/Image_upload_aliyun