又又又有新需求了,这次又有上传七牛云的需求了,从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: () => {}
})
})
}