小程序阿里云oss直传

1,688 阅读3分钟

小程序阿里云oss直传

阿里云直传不需要经过我们项目服务器做一层代理,不仅可以提高我们图片or视频是上传速度,还可以减轻项目服务器的压力。

阿里云官网oss 直传文档参考链接

步骤:

  1. 上方文档链接中关于配置Bucket跨域访问配置微信小程序白名单方面不再赘述。
  2. 先调用微信选择图片or视频的api:wx.chooseMedia获取上传资源的相关信息。(其他相关api也可)
  3. 获取签名一般都是由后端提供一个接口,给前端提供小程序相关签名信息。
  4. 前端从接口中取出需要的字段:
    • host 阿里云oss存储链接
    • signature 签名
    • accessKey
    • policy
    • ...
  5. 在获取到签名信息的接口的回调函数中,调用小程序的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:

chooseMedia.png

题外:关于wx.chooseMedia不同系统返回值不同问题的相关记录

在开发过程中,由于项目需要支持可以上传多张图片or视频,所以选用小程序的wx.chooseMediaapi。api会给我们返回一个数组,包含上传文件的文件大小,文件类型及临时路径等相关信息。在开发者工具中,tempFiles数组中的每一项都包含了一个fileType字段,该字段为文件类型。(如上图所示)。因为上传了不同类型的文件,前端需要给后端传值的时候存储一个文件类型字段,用于查看详情时判断图片or视频的回显,当时想都没想就直接取数组中的每一项itemfileType,后续测试时,发现ios上传视频后查看详情的视频预览总是无法加载出来,经过一番对比,终于找出原因。下图为两个系统上传视频文件的返回体对比展示:

  • ioswx.chooseMedia的response: ios.png

  • 安卓wx.chooseMedia的response: 安卓.png

解决方法:wx.chooseMedia虽然可以上传图片or视频,但是在多选的情况下只能要么选图片上传,要么选视频上传,二者只能选择一个类型传完再选另一个类型,所以,当你上传完之后,同一次上传完的类型必定是一致的。在response的最外层有一个type字段则是该次上传的文件类型。用该字段可以作为文件类型为前端传值做一个区别判定。