vue项目使用阿里云oss上传,大文件上传

1.首先下载oss
执行:
npm install ali-oss

2.在项目中,配合element中upload组件使用,引入oss的js文件
import fileMixin from '@/mixins/file' (已贴代码)
在upload组件的handleBeforeUpload中判断oss初始化是否成功
在这里插入图片描述

3.在handleHttpRequest中做上传判断
(saveOssResource后端接口 此处不贴代码了)
在这里插入图片描述

  1. 封装成单独的js代码 例如名为file.js 放入/mixins/file’ 代码如下
import {
  checkOssClient,
  initOssClient
} from '@/utils/upload'
import {
  downloadFile
} from '@/utils/file'
// 下载的方法
const moment = require('moment')
let client = null

export default {
  methods: {
    async initAliOssClient() {
      // 检查是否已有 Oss Client
      client = checkOssClient()

      if (!client) {
        try {
          await this.$api
            .getResourceOssToken({})
            .then((res) => {
              const credentials = res.data
              client = initOssClient(
                credentials.accessKeyId,
                credentials.accessSecret,
                credentials.securityToken,
                credentials.region,
                credentials.bucket,
                credentials.expiration,
              )
            })
        } catch (error) {
          this.$message.error(`${error}`)
          return
        }
      }

      return client
    },

    // 文件上传至 oss
    async uploadFileToAliOss(opt, {
      callback
    }) {
      // 获取文件后缀
      const tmp = opt.file.name.split('.')
      const extname = tmp.pop().toLowerCase()
      const day = moment().format('YYYY-MM-DD')

      // 生产随机文件名
      const randomName = Array(32)
        .fill(null)
        .map(() => Math.round(Math.random() * 16).toString(16))
        .join('')
      const path = `/${extname}/${day}/${randomName}.${extname}`

      let url

      try {
        let resourceName = opt.file.name
        // 使用 multipartUpload 正式上传到 oss
        const res = await client.multipartUpload(path, opt.file, {
          progress: async function (p) {
            // progress is generator
            let e = {}
            e.percent = p * 100
            // 上传进度条,el-upload 组件自带的方法
            opt.onProgress(e)
          },
          headers: {
            'Content-Type': `application/octet-stream`,
            'Content-Disposition': 'attachment;filename=' + encodeURIComponent(resourceName),
            'x-oss-object-acl': 'public-read'
          }
        })

        // 去除 oss 分片上传后返回所带的查询参数,否则访问会 403
        const ossPath = res.res.requestUrls[0].split('?')[0]
        // 替换协议,统一使用 'https://',否则 Android 无法显示图片
        url = ossPath.replace('http://', 'https://')
      } catch (error) {
        console.log(error, 'error')
        this.$message.error('文件上传失败或取消')
        return
      }

      const {
        size,
        name,
        uid
      } = opt.file

      callback({
        url,
        size,
        name,
        originPath: path.substring(path.indexOf('/') + 1, path.length),
        uid,
      })
    },

    // 下载文件
    downloadFile(file) {
      if (file?.oid) {
        this.getFileDownloadInfo(file.oid, (fileUrl) => {
          downloadFile({
            url: fileUrl
          })
        })
      }
    },

    // 获取文件下载信息
    getFileDownloadInfo(oid, callback) {
      this.$api
        .getFileDownloadInfo({
          oid
        })
        .then(response => {
          const {
            data
          } = response

          // 该文件的上传类型(阿里云oss 或 默认上传)不同
          // 返回的文件下载也不同
          // 可能是阿里云oss,也可能是默认上传ftp地址
          if (data) callback(data)
        })
        .catch(error => {
          console.log('getFileDownloadInfo error', error)
        })
    }
  },
}

引用的oss方法,放入utils/upload中,代码如下

const OSS = require('ali-oss')
const moment = require('moment')

const env = process.env.NODE_ENV

let expirationTime = null // STS token 过期时间
let client = null // OSS Client 实例

const bucket = {
  development: 'local-test-bucket-t',
  dev: 'filesdev',
  pre: 'filespre',
  beta: 'filespro',
  production: 'filespro'
}

// 初始化 oss client
export function initOssClient(accessKeyId, accessKeySecret, stsToken, region, bucket, expiration) {
  client = new OSS({
    accessKeyId,
    accessKeySecret,
    stsToken,
    region,
    bucket,
    secure: true
  })
  expirationTime = expiration
  return client
}

// 检查 oss 实例以及过期时间
export function checkOssClient() {
  const current = moment()
  return moment(expirationTime).diff(current) < 0 ? null : client
}

// 用于 sts token 失效、用户登出时注销 oss client
export function destroyOssClient() {
  client = null
}

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值