VUE + Element-UI 上传到阿里云OSS

8,476 阅读2分钟

什么是OSS?

首先看一下官网的说明。我是官网文档链接

阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。其数据设计持久性不低于 99.999999999%,服务设计可用性不低于 99.99%。OSS 具有不受平台限制的 RESTful API 接口,您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

您可以使用阿里云提供的 API、SDK 接口或者 OSS 迁移工具轻松地将海量数据移入或移出阿里云 OSS。数据存储到阿里云 OSS 以后,您可以选择标准类型(Standard)的阿里云 OSS 服务作为移动应用、大型网站、图片分享或热点音视频的主要存储方式,也可以选择成本更低、存储期限更长的低频访问类型(Infrequent Access)和归档类型(Archive)的阿里云 OSS 服务作为不经常访问数据的备份和归档。

简单理解,就是一个大型的Object

{
    parent
    {
        children
    }
}

怎么使用?

官网提供了多种语言版本的SDK示例,我这里使用的是Node版本的。

  1. 使用 NPM 安装ali-oss

    Node.js >= 8.0.0 如果需要在 Node.js < 8 的环境中使用,请使用 ali-oss 4.x版本。

npm install ali-oss
  1. 创建实例,OSS NodeJS SDK同时支持同步和异步的使用方式
  • 同步方式:基于async和await方式,异步编程同步化
  • 异步方式:类似callback的方式,API接口返回Promise,使用.then()处理返回结果,使用.catch()处理错误

ali-oss.js

// 引入ali-oss
let OSS = require('ali-oss')

/**
 *  [accessKeyId] {String}:通过阿里云控制台创建的AccessKey。
 *  [accessKeySecret] {String}:通过阿里云控制台创建的AccessSecret。
 *  [bucket] {String}:通过控制台或PutBucket创建的bucket。
 *  [region] {String}:bucket所在的区域, 默认oss-cn-hangzhou。
 */
let client = new OSS({
   region: '<oss region>',
  //云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,部署在服务端使用RAM子账号或STS,部署在客户端使用STS。
  accessKeyId: '<Your accessKeyId>',
  accessKeySecret: '<Your accessKeySecret>',
  bucket: '<Your bucket name>'
})

  1. 调用API的方法

ali-oss.js

/**
 *  上传文件,大小不能超过5GB
 * @param {string} ObjName OSS的储存路径和文件名字
 * @param {string} fileUrl 本地文件
 *
 * @retruns Promise
 */
export const put = async (ObjName, fileUrl) => {
  try {
    let result = await client.put(`AAA/${ObjName}`, fileUrl)
    // AAA为文件夹, ObjName为文件名字,可以只写名字,就直接储存在 bucket 的根路径
    console.log(result)
    return result
  } catch (e) {
    console.log(e)
  }
}

官网方法示例点这里

使用Element-UI的 Upload 组件封装上传

Element-UI的 Upload 组件有一个 http-request 配置,可以自定义上传方法,覆盖默认的。

直接贴代码

<template>
  <div class="hello">
    <el-upload
      class="upload-demo"
      action
      :http-request="handleUpload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :before-remove="beforeRemove"
      multiple
      :limit="limit"
      :on-exceed="handleExceed"
      :file-list="fileList"
      :list-type="listType"
    >
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">{{ tip }}</div>
    </el-upload>
  </div>
</template>

<script>
import { put, getFileNameUUID } from '@/utils/ali-oss'

export default {
  name: 'Upload',
  props: {
    tip: {
      type: String,
      default: '上传大小不能超过80M'
    },
    limit: {
      type: Number,
      default: 1
    },
    action: {
      type: String,
      default: ''
    },
    headers: {
      type: Object,
      default: () => {}
    },
    name: {
      type: String,
      default: ''
    },
    listType: {
      type: String,
      default: 'text'
    }
  },
  data() {
    return {
      fileList: []
    }
  },
  methods: {
    handleRemove(file, fileList) {
      this.$emit('on-remove', file, fileList)
    },
    handlePreview(file) {
      this.$emit('on-preview', file)
    },
    handleExceed(files, fileList) {
      this.$message.warning(`每次只能上传 ${this.limit} 个文件`)
    },
    beforeRemove(file, fileList) {
      return this.$confirm(`确定移除 ${file.name}?`)
    },
    handleSuccess(response, file, fileList) {
      this.fileList = fileList
      this.$emit('on-success', file, fileList)
    },
    /**
     * 自定义上传方法
     */
    handleUpload(option) {
        // 生成的文件名称
      let objName = getFileNameUUID()
      
      // 调用 ali-oss 中的方法
      put(`aaaaaa${objName}`, option.file).then(res => {
        console.log(res)
      })
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

提交到后台保存文件地址

上传到阿里云OSS成功后,会返回文件的地址,提交给后台保存地址就可以了。

UUID的生成算法有多种多样,这里把我用的贴出来,仅供参考


/**
 * 生成随机文件名称
 * 规则八位随机字符,加下划线连接时间戳
 */
export const getFileNameUUID = () => {
  function rx() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
  }
  return `${+new Date()}_${rx()}${rx()}`
}