axios 直传 oss

oss.js

'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.indexOf('.')) // 文件扩展名

    var query = { module: type }
    getSign(query).then(response => {
      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)
      }).then(error => {
        option.onError(error)
      })
    })
  },
  // 转化 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 }) {
    var that = this
    const extensionName = file.name.substr(file.name.indexOf('.')) // 文件扩展名

    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 的错误
        axios({
          url: sign.host,
          method: 'post',
          onUploadProgress: function(progressEvent) { // 原生获取上传进度的事件
            if (progressEvent.lengthComputable) {
              // 属性lengthComputable主要表明总共需要完成的工作量和已经完成的工作是否可以被测量
              // 如果lengthComputable为false,就获取不到progressEvent.total和progressEvent.loaded
              // option.onProgress(progressEvent)
            }
          },
          data: param
        }).then(res => {
          res.url = sign.host + '/' + fileName
          if (okCallback) okCallback(res)
        }).then(error => {
          if (error) {
            if (errCallback) {
              errCallback(error)
            } else {
              console.warn(`上传文件到阿里云 OSS 发生错误:${error}`)
            }
          }
        })
      } else {
        Message({
          type: 'error',
          message: 'oss 服务发生错误,请重试或联系管理员'
        })
      }
    })
  },
  analysisCoverAli: function(filePath) {
    analysisCover(filePath)
  }
}

调用

oss.ossUploadFile({
  option: this.uploadQueue[0],
  type: 'video'
})

Last updated

Was this helpful?