微信小程式開發 -- 通過雲函式下載任意檔案

Kindear_chen發表於2020-05-27

微信小程式開發 -- 通過雲函式下載任意檔案

1.雲開發介紹

​ 微信小程式開發者眾所周知,小程式開發擁有許多限制,當我還是一個菜鳥入門的時候,第一關就卡在了沒有備案域名的HTTP請求上面,那時候雲開發上線也沒多久,使用的人也不是很多,我抱著嘗試的態度去接觸了雲開發,發現了雲開發的妙處。(自由)

blog:微信小程式HTTP訪問連結解決方案

2.小程式檔案下載限制

微信小程式除了對訪問地址有限制之外,對於檔案下載,也存在的限制,如下圖所示,只有資源伺服器A,在downloadFile域名白名單內且配置了SSL訪問,即HTTPS才可以正常的下載資源。(閒的蛋疼,飽受詬病)

3.雲函式下載任意檔案設計

依然秉持著對雲開發的信任,嘗試使用雲函式進行任意檔案下載,設計思路如下圖所示。

上圖描述的兩種通過雲函式下載檔案的方式

  1. 雲函式只作為一個資料中轉節點,請求資源轉化為Buffer直接返回給小程式端。
  2. 雲函式作為儲存器,下載資源儲存到雲空間,並返回給小程式端fileID(置換下載地址)。

4.雲函式實現方式

通過請求頭配置實現請求資原始檔返回Buffer。

const cloud = require('wx-server-sdk')
const request = require('request')
const fs = require('fs')
const path = require('path')
cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database(); //初始化雲資料庫
exports.main = async (event, context) => {
  var url = event.url; //下載地址,應該由前端進行傳遞,而後雲函式進行下載
  var type = event.type; //type:'dump'(轉儲) 'trans'(傳遞)
  var filename = event.filename;
  //檔名稱需要自己進行上傳,或者substring 擷取url
  var options = {
    url: url,
    encoding: null,
    headers: {
      "content-type": "application/octet-stream",
    },
  };
  return new Promise(function (resolve, reject) {
    request(options, function (error, response, body) {
      if(type=='trans'){
          //中繼
        resolve(body)
      }else{
          //轉儲
        resolve(
          cloud.uploadFile({
            cloudPath: 'tmp/'+filename,
            fileContent: body,
          })
        )
      }
    })
  })
}

5.中繼下載方式(不推薦,適合小檔案)

如果檔案達到一定體積,會出現如下問題:

中繼下載方式對檔案的大小有限制,這是由於雲函式返回限制決定的,很容易超出。但是對於一些幾kb的檔案,推薦使用這種方式,減少了轉儲所需要耗費的時間。

中繼方式下載資源寫法如下:

   var _filename = '美景.jpg';
   var _url = 'http://img.apisev.cn:8081/wechat/sk1.jpg';
    wx.cloud.callFunction({
      name:'transfile',
      data:{
        url:_url,
        filename:_filename,
        type:'trans'
      },
      success(res){
        console.log(res)
        const FileSystemManager = wx.getFileSystemManager();
        FileSystemManager.writeFile({
          filePath:wx.env.USER_DATA_PATH+"/"+_filename,
          data:res.result,
          encoding: 'binary',//編碼方式,二進位制
          success(tres){
            console.log(tres)
            //可以根據filePath 開啟檔案,此處以為圖片舉例
            var _filepath = wx.env.USER_DATA_PATH+"/"+_filename;
            wx.previewImage({
              urls: [_filepath],
            })
          },fail(tres){
            console.log(tres)
          }
        })
      },fail(res){
        console.log(res)
      }
    })

真機執行,可以成功預覽資源圖片。

6.轉儲下載方式(推薦)

首先在網際網路資源隨便找了一個圖片資源地址,呼叫雲函式。

var _filename = '美景.jpg';
var _url = 'https://n.sinaimg.cn/sinacn20106/212/w2048h1364/20190828/cded-icuacsa3953451.jpg';
wx.cloud.callFunction({
      name:'transfile',
      data:{
        url:_url,
        filename:_filename,
        type:'dump'
      },
      success(res){
        console.log(res)
      },fail(res){
        console.log(res)
      }
 })

返回內容如下:

圖片成功被轉存到雲端儲存空間。

7.參考文件

[1] FileSystemManager.writeFile(Object object)

相關文章