oss 直传对象存储

'use strict'
import Utils from './utils'
import { getSign, analysisCover } from '@/api/oss'
import { Message } from 'element-ui'
import axios from 'axios'

export default {

  /**
   * 创建随机字符串
   * @param num
   * @returns {string}
   */
  randomString(num) {
    const chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    let res = ''
    for (let i = 0; i < num; i++) {
      var id = Math.ceil(Math.random() * 35)
      res += chars[id]
    }
    return res
  },

  /**
   * 创建oss客户端对象
   * @returns {*}
   */
  createOssClient(sign) {
    return new Promise((resolve, reject) => {
      // eslint-disable-next-line no-undef
      const client = new OSS({
        region: 'oss-cn-hangzhou',
        accessKeyId: '*',
        accessKeySecret: '*',
        bucket: '*'
      })
      resolve(client)
    })
  },
  /**
   * 文件上传
   * @param option 参考csdn: https://blog.csdn.net/qq_27626333/article/details/81463139
   */
  ossUploadFile: function({ option, type }) {
    const file = option.file
    const extensionName = file.name.substr(file.name.lastIndexOf('.')) // 文件扩展名

    var query = { module: type }
    getSign(query).then(response => {
      if (response.ok === true) {
        const sign = response.data
        const dateTime = Utils.dateFormat(new Date(), 'yyyyMMddhhmmss') // 当前时间
        const randomStr = this.randomString(4)//  4位随机字符串
        const fileName = sign.dir + '/' + dateTime + '_' + randomStr + extensionName // 文件名字(相对于根目录的路径 + 文件名)
        const name = file.name // 获取图片的名称
        const param = new FormData()
        param.append('key', fileName) // 存储到oss的图片名称 自己定,必须确保唯一性,不然会覆盖oss中原有的文件
        param.append('policy', sign.policy) // 服务器提供 policy
        param.append('OSSAccessKeyId', sign.accessid) // 服务器提供 access_id
        param.append('success_action_status', 200)
        param.append('callback', sign.callback) // oss服务端的回调,服务器提供
        param.append('callback_var', sign.callbackVar) // oss服务端的回调,服务器提供
        param.append('signature', sign.signature) // 这个就是签名,最关键的,服务器提供
        param.append('file', file, name) // 这个切记一定要放到最后去 append ,不然阿里云会一直报 key 的错误

        const CancelToken = axios.CancelToken
        const source = CancelToken.source()
        axios({
          url: sign.host,
          method: 'post',
          onUploadProgress: function(progressEvent) { // 原生获取上传进度的事件
            if (progressEvent.lengthComputable) {
              progressEvent.cancelSource = source
              // 属性lengthComputable主要表明总共需要完成的工作量和已经完成的工作是否可以被测量
              // 如果lengthComputable为false,就获取不到progressEvent.total和progressEvent.loaded
              option.onProgress(progressEvent)
            }
          },
          data: param,
          cancelToken: source.token
        }).then(res => {
          res.url = sign.host + '/' + fileName
          option.onSuccess(res)
        }).catch(error => {
          if (error) {
            option.onError(error)
          }
        })
      } else {
        option.onError(response)
      }
    })
  },
  // 转化 base64 为 blob
  dataURItoBlob: (dataURI) => {
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0] // mime类型
    var byteString = atob(dataURI.split(',')[1]) // base64 解码
    var arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组
    var intArray = new Uint8Array(arrayBuffer) // 创建视图

    for (var i = 0; i < byteString.length; i++) {
      intArray[i] = byteString.charCodeAt(i)
    }
    return new Blob([intArray], { type: mimeString })
  },
  ossSimpleUpload({ type, file, okCallback, errCallback }) {
    if (file.name != null) {
      var that = this
      const extensionName = file.name.substr(file.name.lastIndexOf('.')) // 文件扩展名

      var query = { module: type }
      getSign(query).then(response => {
        if (response.ok === true) {
          const sign = response.data
          const dateTime = Utils.dateFormat(new Date(), 'yyyyMMddhhmmss') // 当前时间
          const randomStr = that.randomString(4)//  4位随机字符串
          const fileName = sign.dir + '/' + dateTime + '_' + randomStr + extensionName // 文件名字(相对于根目录的路径 + 文件名)
          const name = file.name // 获取图片的名称
          const param = new FormData()
          param.append('key', fileName) // 存储到oss的图片名称 自己定,必须确保唯一性,不然会覆盖oss中原有的文件
          param.append('policy', sign.policy) // 服务器提供 policy
          param.append('OSSAccessKeyId', sign.accessid) // 服务器提供 access_id
          param.append('success_action_status', 200)
          param.append('callback', sign.callback) // oss服务端的回调,服务器提供
          param.append('callback_var', sign.callbackVar) // oss服务端的回调,服务器提供
          param.append('signature', sign.signature) // 这个就是签名,最关键的,服务器提供
          param.append('file', file, name) // 这个切记一定要放到最后去 append ,不然阿里云会一直报 key 的错误

          const CancelToken = axios.CancelToken
          const source = CancelToken.source()
          axios({
            url: sign.host,
            method: 'post',
            onUploadProgress: function(progressEvent) { // 原生获取上传进度的事件
              if (progressEvent.lengthComputable) {
                // 将取消上传事件返回
                progressEvent.cancelSource = source
                // 属性lengthComputable主要表明总共需要完成的工作量和已经完成的工作是否可以被测量
                // 如果lengthComputable为false,就获取不到progressEvent.total和progressEvent.loaded
                file.onProgress(progressEvent)
              }
            },
            data: param,
            cancelToken: source.token
          }).then(res => {
            res.url = sign.host + '/' + fileName
            if (okCallback) okCallback(res)
          }).catch(error => {
            if (error) {
              if (errCallback) {
                console.log(error)
                if (error.message.code !== 30002) {
                  Message({
                    type: 'error',
                    message: 'oss 服务发生异常,请反馈给管理员!'
                  })
                }

                errCallback()
              } else {
                console.warn(`上传文件到阿里云 OSS 发生错误:${error}`)
              }
            }
          })
        } else {
          if (errCallback) errCallback()
        }
      })
    } else {
      return false
    }
  },
  analysisCoverAli: function(filePath) {
    analysisCover(filePath)
  }
}

Last updated