微信小程式開發 -- 通過雲函式下載任意檔案
1.雲開發介紹
微信小程式開發者眾所周知,小程式開發擁有許多限制,當我還是一個菜鳥入門的時候,第一關就卡在了沒有備案域名的HTTP請求上面,那時候雲開發上線也沒多久,使用的人也不是很多,我抱著嘗試的態度去接觸了雲開發,發現了雲開發的妙處。(自由)
blog:微信小程式HTTP訪問連結解決方案
2.小程式檔案下載限制
微信小程式除了對訪問地址有限制之外,對於檔案下載,也存在的限制,如下圖所示,只有資源伺服器A,在downloadFile域名白名單內且配置了SSL訪問,即HTTPS才可以正常的下載資源。(閒的蛋疼,飽受詬病)
3.雲函式下載任意檔案設計
依然秉持著對雲開發的信任,嘗試使用雲函式進行任意檔案下載,設計思路如下圖所示。
上圖描述的兩種通過雲函式下載檔案的方式
- 雲函式只作為一個資料中轉節點,請求資源轉化為Buffer直接返回給小程式端。
- 雲函式作為儲存器,下載資源儲存到雲空間,並返回給小程式端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.參考文件