又又又有新需求了,這次又有上傳七牛云的需求了,從H5換成了小程序,又探了一次坑。
思路一致
1. 首先,獲取Token
和以前一樣,后端來做七牛云Token的獲取,我們只需要調用后端接口,拿到七牛云的接口
2. 獲取本地圖片
因為在微信里,所以直接調用wx的wx.chooseImageapi就行
插一段
在做的時候以為要像H5做的時候一樣將文件流轉一下格式,做了很多工作,反復上傳結果七牛云一直報400的錯誤。最后試了下七牛云推薦的qiniuUploaderjs,可以上傳,讀源碼發現不需要對文件進行轉換
3. 圖片名
因為七牛云上傳需要有一個名字,我這里對文件進行了md5(需要npm install md5js),使用hash值作為圖片的名字,不容易重復。
不過,這里需要對文件進行讀取,需要用到readFile。
注意 微信文檔中是FileSystemManager.readFile(Object object) ,我們實際使用的是wx.getFileSystemManager().readFile()
4. 上傳圖片到七牛云
這里我們直接時候用微信apiwx.uploadFile
這里需要注意的是 微信的api只能上傳本地路徑的圖片,也就是在wx.chooseImage直接拿到的路徑,實測如果上傳readFile后的信息流會失敗。
還是很簡單吧。
下面貼源碼:
我把上傳的步驟都分裝成了各自函數,可以在過程中需要添加什么可以靈活控制。
/**
*調用微信選取照片 返回圖片本地地址
*
* @param {number} [maxCount=1] 默認1張
* @param {string} [sizeType=['original']] 默認原圖
* @param {string} [sourceType=['camera']] 默認從相機
* @returns
*/
const takePhoto = (maxCount = 1, sizeType = ['original'], sourceType = ['camera']) => {
return new Promise((resolve, reject) => {
wx.chooseImage({
count: maxCount, // 最多可以選擇的圖片張數,默認1
sizeType, // original 原圖,compressed 壓縮圖,默認二者都有
sourceType, // album 從相冊選圖,camera 使用相機,默認二者都有
success(res) {
// success
const urlPath = res.tempFilePaths[0]
resolve(urlPath)
},
fail(res) {
// fail
reject(res)
},
complete(res) {
// complete
}
})
})
}
/**
* 文件md5化
*
* @param {*} file
*/
const readFileMd5 = file => {
return new Promise(async (resolve, reject) => {
try {
const fileStream = await ReadFile(file, 'binary')
const md5Key = md5(fileStream)
resolve(md5Key)
} catch (error) {
reject(error)
}
})
}
/**
*調用微信讀取文件流
*
* @param {*} file
* @param {string} [type='binary']
* @returns
*/
const ReadFile = (file, type = 'binary') => {
return new Promise((resolve, reject) => {
wx.getFileSystemManager().readFile({
filePath: file,
encoding: type,
success(res) {
resolve(res.data)
},
fail(res) {
reject(res)
}
})
})
}
/**
*
* 上傳文件到七牛云
* @param {*} token 七牛Token
* @param {*} url 上傳目標地址
* @param {*} file 文件
* @param {*} name 文件名
* @returns
*/
const uploadToQiniu = (token, url, file, name) => {
return new Promise((resolve, reject) => {
wx.uploadFile({
url: url, // 開發者服務器 url
filePath: file, // 要上傳文件資源的路徑
name: 'file', // 文件對應的 key , 開發者在服務器端通過這個 key 可以獲取到文件二進制內容,
formData: {
token,
key: name
},
success: res => {
if (res.statusCode === 200) {
resolve(name)
}else{
reject(res)
}
},
fail: res => {
reject(res)
},
complete: () => {}
})
})
}