版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文要点:
- token的处理
- 上传多张图片时异步问题处理
上传图片一般写法
- 以下代码都有清晰的注释,大家可以结合注释理解
uploadImg () {
const that = this
const imgToken = tool.checkImgToken() // 上传七牛需要的token
wx.chooseImage({
count: 1, // 1次只能传一张
sizeType: ['original', 'compressed'], // 原图,压缩图均可
sourceType: ['album', 'camera'], // 图片来源可以是相册也可以是相机拍摄
success (res) {
const tempUrl = res.tempFilePaths[0] // 临时图片列表,这里只有一张
wx.uploadFile({
url: 'https://upload-z2.qiniup.com',
name: 'file',
filePath: tempUrl,
header: {
'Content-Type': 'multipart/form-data'
},
formData: {
token: imgToken
},
success: function (res) {
let temp = JSON.parse(res.data)
that.imageUrl = tool.IMGURL + temp.key // 拼接key得正式图片地址,后续通过保存存入后台
}
})
}
})
},
以上代码的关键点:
- token每次都去请求接口拿吗?
- token一般会有一个指定时长的有效期,我们项目中是1小时;
- 一些人说token的有效期可以配置,为什么不配置时间长一点;
- 比如配置token的有效期为100年,伴随而来的问题是:其他用户拿到这个token可以几乎不受限制地一直上传文件;
- 可想而知,一旦token泄露,后果自行脑补。
对于1小时有效期的token我们如何处理?
- 以下代码都有清晰的注释,大家可以结合注释理解
function checkImgToken () {
const now = (new Date()).getTime() // 当前时间戳
const tempInfo = wx.getStorageSync('tokenInfo') // 缓存中的token信息,包括token过期时间
const expire = new Date(tempInfo.expireDate).getTime() // 过期时间的时间戳
if (expire - now > 0) {
// 如果过期时间戳大于当前时间戳,则直接在缓存把token拿来用
return tempInfo.token
} else {
// 否则,重新请求后台接口拿新的token
return axios(api.imgToken).then(res => {
if (res.code === 1) {
// 拿到新的token后存入缓存
wx.setStorageSync('tokenInfo', res.data)
return res.data.token
}
})
}
}
上传图片的优化写法
- 结合async/await处理异步问题
async uploadImg (index) {
const that = this
const imgToken = await tool.checkImgToken()
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success (res) {
const tempUrl = res.tempFilePaths[0]
wx.uploadFile({
url: 'https://upload-z2.qiniup.com',
name: 'file',
filePath: tempUrl,
header: {
'Content-Type': 'multipart/form-data'
},
formData: {
token: imgToken
},
success: function (res) {
let temp = JSON.parse(res.data)
that.imageUrl = tool.IMGURL + temp.key
}
})
}
})
},
一次上传多张图片
- 借助new Promise实现多张图片一起上传,当全部上传成功后返回正式的picList
- 以下代码都有清晰的注释,大家可以结合注释理解
async uploadImg () {
const that = this
const imgToken = await tool.checkImgToken()
// picLength为已经上传图片的数量,最多20张
if (that.picLength < 20) {
wx.chooseImage({
count: 20 - that.picLength,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success (res) {
that.uploadAll(res.tempFilePaths, imgToken)
}
})
}
},
uploadAll (arr, token) {
const that = this
const imgList = []
let count = 0
// 由于一次上传多张,可能用时有点长,加个loading提示用户
wx.showLoading({
title: '正在上传...',
mask: true
})
new Promise((resolve, reject) => {
for (var i = 0; i < arr.length; i++) {
wx.uploadFile({
url: 'https://upload-z2.qiniup.com',
name: 'file',
filePath: arr[i],
header: {
'Content-Type': 'multipart/form-data'
},
formData: {
token
},
success: function (res) {
count++
let temp = JSON.parse(res.data)
imgList.push({
imageUrl: tool.IMGURL + temp.key
})
// 当全部上传成功后resolve出结果,否则进入循环上传的下一项
if (count === arr.length) {
resolve(imgList)
}
}
})
}
}).then(list => {
const tempArr = that.picList.concat(list)
// 全部上传完隐藏loading
wx.hideLoading()
that.$emit('setImages', tempArr)
})
},
注:有些图片在使用wx.chooseImage上传多张图片时得到的临时数组长度和选择的长度不一致,如选择9张只返回5张临时图片,暂无好的解决方案。(发现机型一加手机)