小程序阿里云oss直传
阿里云直传不需要经过我们项目服务器做一层代理,不仅可以提高我们
图片or视频是上传速度,还可以减轻项目服务器的压力。
步骤:
- 上方文档链接中关于
配置Bucket跨域访问和配置微信小程序白名单方面不再赘述。 - 先调用微信选择
图片or视频的api:wx.chooseMedia获取上传资源的相关信息。(其他相关api也可) - 获取签名一般都是由后端提供一个接口,给前端提供小程序相关签名信息。
- 前端从接口中取出需要的字段:
- host 阿里云oss存储链接
- signature 签名
- accessKey
- policy
- ...
- 在获取到签名信息的接口的回调函数中,调用小程序的
wx.uploadFile,实现文件直传
上代码:
wx.chooseMedia({
count: 9,
mediaType: ['image','video'],
sourceType: ['album', 'camera'],
maxDuration: 30,
camera: 'back',
success(res) {
console.log(res.tempFiles) // tempFiles是一个数组,具体返回请看下方图片
let list = res.tempFiles.map(item => {
let fileType = res.type // ios 的 tempFiles 每一项不返回 fileType 属性,取最外层的type
return {
tempFilePath: item.tempFilePath, // 临时文件路径
fileType, // 上传的文件类型
}
})
list.forEach(item => {
// httpGet为封装的请求方法,调用后端接口获取签名认证信息
util.httpGET('ossPolicy', {
folder: `${item.fileType}s`, // 上传的文件类型:图片或视频
subFolder: 'skynet' // 阿里存储文件夹目录
}, (resp) => {
console.log('resp:', resp)
if (resp.code == 0) {
// dir:阿里云存储的文件夹名称
const { accessid, dir, host, policy, signature } = resp.data
let link = item.tempFilePath.slice(11) // 截取前面的临时文件名作为上传文件的文件名
let key = `${dir}${link}` // 阿里云文件具体目录
wx.uploadFile({
url: host, // 阿里云oss地址
filePath: item.tempFilePath, // 选择图片或视频之后返回的临时文件地址
name: 'file',
formData: {
key,
OSSAccessKeyId: accessid,
policy,
signature,
},
success: (response) => {
console.log('response:', response)
if (response.statusCode === 204) {
// 根据需要做相关操作,存储需要给后端传递的参数值。
}
}
})
}
})
})
}
})
- wx.chooseMedia的res:
题外:关于wx.chooseMedia不同系统返回值不同问题的相关记录
在开发过程中,由于项目需要支持可以上传多张
图片or视频,所以选用小程序的wx.chooseMediaapi。api会给我们返回一个数组,包含上传文件的文件大小,文件类型及临时路径等相关信息。在开发者工具中,tempFiles数组中的每一项都包含了一个fileType字段,该字段为文件类型。(如上图所示)。因为上传了不同类型的文件,前端需要给后端传值的时候存储一个文件类型字段,用于查看详情时判断图片or视频的回显,当时想都没想就直接取数组中的每一项item的fileType,后续测试时,发现ios上传视频后查看详情的视频预览总是无法加载出来,经过一番对比,终于找出原因。下图为两个系统上传视频文件的返回体对比展示:
-
ios中wx.chooseMedia的response: -
安卓中wx.chooseMedia的response:
解决方法:
wx.chooseMedia虽然可以上传图片or视频,但是在多选的情况下只能要么选图片上传,要么选视频上传,二者只能选择一个类型传完再选另一个类型,所以,当你上传完之后,同一次上传完的类型必定是一致的。在response的最外层有一个type字段则是该次上传的文件类型。用该字段可以作为文件类型为前端传值做一个区别判定。