uniapp 阿里云 oss 上传文件/图片

项目背景: uniapp  开发的 混合项目,包含 H5, ios,  android  三端开发;看了下 本身 alioss  是有提供 JS SDK,但是考虑到兼容问题,所以采用了 PostObject 方式,来上传 aliyunoss , 官方的文档:PostObject - 对象存储 OSS - 阿里云https://help.aliyun.com/document_detail/31988.html

大体流程

  1. 向自己的服务器  请求操作  阿里云OSS token 权限
  2. 将文件上传至 阿里云OSS ,这里有个小插曲 ,分了两只情况:等下在后面具体分析两种情况
    1,使用 uniapp 的  uni.chooseImage 选择图片/或者拍照,拿到的文件
    
    2,是用 H5 input 方式拿到的 图片信息
    
    
  3. 将拿到上传成功的文件信息 通知到 自己的服务器,

uniapp 通过 input 选择的文件 处理:

 在这里通过  event.path[0].files[0]  拿到文件具体信息:

input.onchange = async(event) => {
  // console.log('event------------->', event)
  // console.log('event------------->', event.target)
  const tempSize = event.path[0].files[0].size
  const size = tempSize / 1024 / 1024
  if (size > 5) {
    uni.showModal({
      content: 'Please upload a file no more than 5M!',
      confirmText: 'Confirm',
      showCancel: false
    })
    return
  }

  const resoult = await aliOssHelper.aliOssUploadH5({
    file: event.path[0].files[0]
  })
  if (resoult.code === 200) {
    this.$emit('fileUploadInfo', resoult)
  }
}

核心的处理函数,将图片 转成 base64,直接 扔给  uni.uploadFile

  async upLoadFileH5(option) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.readAsDataURL(option.file)
      reader.onload = (date) => {
        const fileInfo = this.fileNameByfile(option.file)
        const resoult = {
          sucess: false,
          filePath: fileInfo.path,
          name: fileInfo.name,
          url: `${store.state.aliOssToken.domain}${fileInfo.path}`
        }
        uni.uploadFile({
          url: `https://${store.state.aliOssToken.bucketName}.${store.state.aliOssToken.endPoint}`,
          // url: 'https://test-gbm001-oss.oss-cn-hangzhou.aliyuncs.com',
          filePath: date.target.result,
          fileType: option.file.type,
          name: 'file',
          formData: {
            key: fileInfo.path,
            policy: store.state.aliOssToken.encodedPolicy,
            OSSAccessKeyId: store.state.aliOssToken.accessKeyId,
            success_action_status: '200', // 让服务端返回200,不然,默认会返回204
            signature: store.state.aliOssToken.signature
          },
          success: res => {
            if (res.statusCode === 200) {
              console.log('oss upload success 200:', res)
              resoult.sucess = true
              resolve(resoult)
            } else {
              resoult.message = res.errMsg
              console.log('oss upload fail !200:', res)
              resoult.sucess = false
              reject(resoult)
            }
          },
          fail: err => {
            console.log('err:', err)
            resoult.sucess = false
            reject(resoult)
          }
        })
      }
    })

uniapp 通过 uni.chooseImage 选择的图片处理:

 async upLoadFileUni(option) {
    // console.log("option:", option)
    return new Promise((resolve, reject) => {
      const fileInfo = this.fileNameByBlob(option)
      // console.log('fileInfo>>>>>:', fileInfo)
      const resoult = {
        sucess: false,
        message: '',
        filePath: fileInfo.path,
        name: fileInfo.name,
        url: `${store.state.aliOssToken.domain}${fileInfo.path}`
      }
      // console.log('resoult>>>>>:', resoult)
      uni.uploadFile({
        url: `https://${store.state.aliOssToken.bucketName}.${store.state.aliOssToken.endPoint}`,
        filePath: option.file,
        // fileType: option.type,
        name: 'file',
        formData: {
          key: fileInfo.path,
          policy: store.state.aliOssToken.encodedPolicy,
          OSSAccessKeyId: store.state.aliOssToken.accessKeyId,
          success_action_status: '200', // 让服务端返回200,不然,默认会返回204
          signature: store.state.aliOssToken.signature
        },
        success: res => {
          if (res.statusCode === 200) {
            console.log('oss upload success 200:', res)
            resoult.sucess = true
            resolve(resoult)
          } else {
            resoult.message = res.errMsg
            console.log('oss upload fail !200:', res)
            resoult.sucess = false
            reject(resoult)
          }
        },
        fail: err => {
          console.log('err:', err)
          resoult.sucess = false
          reject(resoult)
        }
      })
    })
  },

完整的脚本  aliOssHelper.js

//羡慕封装的 http请求函数
import {
  flyio
} from '@/utils/api/config.js'
//保存 服务端传来的 alioss 权限数据
import store from '@/store/index'
//自己分装的 时间格式化
import time from '@/common/time.js'
export default {
  async aliOssUploadH5(option) {
    await this.aliOssTokeCheck()
    const resoult = await this.upLoadFileH5(option)
    if (resoult.sucess) {
      return await this.syncToServer(resoult)
    } else {
      uni.showToast({
        title: 'upLoad to server fail',
        icon: 'none'
      })
    }
  },
  async aliOssUploadUni(option) {
    await this.aliOssTokeCheck()
    const resoult = await this.upLoadFileUni(option)
    if (resoult.sucess) {
      return await this.syncToServer(resoult)
    } else {
      uni.showToast({
        title: 'upLoad to server fail',
        icon: 'none'
      })
    }
  },
  async upLoadFileUni(option) {
    // console.log("option:", option)
    return new Promise((resolve, reject) => {
      const fileInfo = this.fileNameByBlob(option)
      // console.log('fileInfo>>>>>:', fileInfo)
      const resoult = {
        sucess: false,
        message: '',
        filePath: fileInfo.path,
        name: fileInfo.name,
        url: `${store.state.aliOssToken.domain}${fileInfo.path}`
      }
      // console.log('resoult>>>>>:', resoult)
      uni.uploadFile({
        url: `https://${store.state.aliOssToken.bucketName}.${store.state.aliOssToken.endPoint}`,
        filePath: option.file,
        // fileType: option.type,
        name: 'file',
        formData: {
          key: fileInfo.path,
          policy: store.state.aliOssToken.encodedPolicy,
          OSSAccessKeyId: store.state.aliOssToken.accessKeyId,
          success_action_status: '200', // 让服务端返回200,不然,默认会返回204
          signature: store.state.aliOssToken.signature
        },
        success: res => {
          if (res.statusCode === 200) {
            console.log('oss upload success 200:', res)
            resoult.sucess = true
            resolve(resoult)
          } else {
            resoult.message = res.errMsg
            console.log('oss upload fail !200:', res)
            resoult.sucess = false
            reject(resoult)
          }
        },
        fail: err => {
          console.log('err:', err)
          resoult.sucess = false
          reject(resoult)
        }
      })
    })
  },
  async upLoadFileH5(option) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.readAsDataURL(option.file)
      reader.onload = (date) => {
        const fileInfo = this.fileNameByfile(option.file)
        const resoult = {
          sucess: false,
          filePath: fileInfo.path,
          name: fileInfo.name,
          url: `${store.state.aliOssToken.domain}${fileInfo.path}`
        }
        uni.uploadFile({
          url: `https://${store.state.aliOssToken.bucketName}.${store.state.aliOssToken.endPoint}`,
          // url: 'https://test-gbm001-oss.oss-cn-hangzhou.aliyuncs.com',
          filePath: date.target.result,
          fileType: option.file.type,
          name: 'file',
          formData: {
            key: fileInfo.path,
            policy: store.state.aliOssToken.encodedPolicy,
            OSSAccessKeyId: store.state.aliOssToken.accessKeyId,
            success_action_status: '200', // 让服务端返回200,不然,默认会返回204
            signature: store.state.aliOssToken.signature
          },
          success: res => {
            if (res.statusCode === 200) {
              console.log('oss upload success 200:', res)
              resoult.sucess = true
              resolve(resoult)
            } else {
              resoult.message = res.errMsg
              console.log('oss upload fail !200:', res)
              resoult.sucess = false
              reject(resoult)
            }
          },
          fail: err => {
            console.log('err:', err)
            resoult.sucess = false
            reject(resoult)
          }
        })
      }
    })
  },
  async aliOssTokeCheck() {
    if (store.state.aliOssToken) {
      const expireTimes = store.state.aliOssToken.expire
      const localTime = (new Date()).getTime() / 1000 + 60 * 10
      // token 过期
      if (localTime > expireTimes) {
        console.warn('oss token expire...  get new one')
        await this.aliOssTokenRequest()
      }
    } else {
      await this.aliOssTokenRequest()
    }
  },
  async aliOssTokenRequest() {
    const resoult = await flyio.get('file/oss/generatePolicySignature')
    if (resoult && resoult.code === 200 && resoult.success === true && resoult.data) {
      store.commit('updateOssAliToken', resoult.data)
      console.warn('aliOssToken scuess ')
    } else {
      console.warn('aliOssToken fail :', resoult)
      uni.showToast({
        title: 'oss token fail',
        icon: 'none'
      })
    }
  },
  async syncToServer(ossInfo) {
    const resoult = await flyio.post('file/saveFileInfo', {
      url: ossInfo.url,
      fileName: ossInfo.name
    })
    if (resoult && resoult.code === 200 && resoult.success === true && resoult.data) {
      resoult.data.originName = ossInfo.name
      resoult.data.url = ossInfo.url
      return resoult
    } else {
      uni.showToast({
        title: 'sync to server fail',
        icon: 'none'
      })
    }
  },
  fileNameByfile(file) {
    const index = file.name.lastIndexOf('.')
    const extension = file.name.substr(index)
    const fileName = `${this.uuid(16, 16)}${extension}`
    return {
      path: `gbm/${time.formatTime(new Date(), 'yyyy/MM/dd')}/${fileName}`.toLowerCase(),
      name: fileName.toLowerCase()
    }
  },
  fileNameByBlob(option) {
    const extension = option.type
    const fileName = `${this.uuid(16, 16)}.${extension}`
    return {
      path: `gbm/${time.formatTime(new Date(), 'yyyy/MM/dd')}/${fileName}`.toLowerCase(),
      name: fileName.toLowerCase()
    }
  },
  uuid(len, radix) {
    const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
    const uuid = []
    let i
    radix = radix || chars.length
    if (len) {
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
    } else {
      let r
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
      uuid[14] = '4'
      // Fill in random data.  At i==19 set the high bits of clock sequence as
      // per rfc4122, sec. 4.1.5
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16
          uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r]
        }
      }
    }
    return uuid.join('')
  }
}

猜你喜欢

转载自blog.csdn.net/nicepainkiller/article/details/122533019