阿里云 oss多文件上传

平时在做 oss 上传时,通过都是单个文件上传,但是前几天工作时涉及到多个文件的上传,在所有文件都上传完成后才能再做后续的代码执行。于是在原有的oss上传基础上添加for循环去挨个上传。
介绍一下,oss 的上传可以有两种:

  1. 一种是把所有的文件上传给后端,由后端去传到阿里云oss上,这样不涉及到向后端获取accessKeyId 和bucket等,没有key泄露的风险(适用于C端客户)。
  2. 一种是向后端调接口获取key等数据,存储在本地,需要的时候调用就可以了,key值设置失效时间,一段时间过后,再向后端获取新的key值,减少key泄露(适用于B端客户)。

第一种,我们就不过多介绍了,就平常的调用上传接口,这篇文章主要介绍第二种
所用到的框架:vue + typescript + element-ui +ali-oss
效果:
阿里云 oss多文件上传_第1张图片


<el-row class="toolbar">
    <el-upload
      action="#"
      :auto-upload="false"
      list-type="picture-card"
      ref="modelFormId"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
      :on-change="onChangeFileValid"
      :disabled="isLook"
    >
      <i class="el-icon-plus">i>
    el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="" />
    el-dialog>
    <el-button @click='upload'>开始上传el-button>
  el-row>
  1. 该引入的插件和文件
<script lang="ts">
import Vue from "vue";
import { Component, Prop, Watch } from "vue-property-decorator"; // typescript导入组件装饰器
// 自己写的生成的36位文件名称id标识
import { Common } from "@/assets/js/common";
// 安装 ali-oss 这也是文件上传阿里云时需要用到的
import OSS from "ali-oss";
// 向后端获取oss key的接口
import { getPublicUpOssSTS } from "@/api/download";
@Component({})
export default class Upload extends Vue {
  ossComPath: string = "ictr-tb-commonservice-test"; // 上传文件时文件所在的文件夹地址
  dialogImageUrl: string = ""; // el-upload 放大文件时的url地址
  dialogVisible: boolean = false; // el-upload 是否正在预览文件
  common: any = new Common(); // new 一下common
  pathName: string = ""; // 上传文件的id
  isLoaderVisible: boolean = false; // 上传文件时的标识
  fullscreenLoading: boolean = false; // 正在上传
  file: any = undefined; 

  ossClient: any = {
    region: "oss-cn-beijing",
    accessKeyId: "",
    accessKeySecret: "",
    bucket: "",
    stsToken: ""
  };
  fileList: any[] = [];


 // 点击开始上传按钮
  upload() {
    const loading = this.$loading({
      lock: true,
      text: "Loading",
      spinner: "el-icon-loading",
      background: "rgba(0, 0, 0, 0.7)"
    });
    this.isLoaderVisible = true;
    
    // 判断签名是否过期,如果过期再次向后端获取签名,也就是key
    this.setUploadParam().then(
      async status => {
        loading.close();
        if (status === 200) {
        
    	  // 开始调用上传方法
          this.multipartUpload();
        }
      },
      req => {
        loading.close();
      }
    );
  }

  // 真正开始上传
  async multipartUpload(param) {
    if (this.fileList.length !== 0) {
      this.client = new OSS(this.ossClient);

      let storeAsList: any[] = [];
     //遍历要上传的文件,设置文件唯一名称
      this.fileList.forEach((m, index: number) => {
        // 自定义id键和自定义名称 
        const name = this.common.guid() + this.common.getFileExtendingName(param.name);
        storeAsList.push({
          storeAs: "adcp/DefaultFilePath/fileAnalysisTempSource/" + name,
          m
        });
      });
      // 等待全部上传成功
      await Promise.all(
        storeAsList.map((file, i) => {
          return this.multiBackPath(file.storeAs, file.m);
        })
      );
      //此时已经全部上传成功了
      this.$message.success("所有文件上传成功!");
    }
  }
  multiBackPath(storeAs, param) {
    return new Promise((resolve, reject) => {
      this.client
        .multipartUpload(storeAs, param.raw)
        .then(result => {
          resolve(result);
        })
        .catch(err => {
          if (!this.client.isCancel()) {
            this.isLoaderVisible = false;
            this.$message.warning("上传失败-");
            reject();
          }
        });
    });
  }
文件上传之前判断签名是否过期
  setUploadParam() {
  	// 判断本地是否有已存在oss
    let ossData = JSON.parse(localStorage.getItem("ossdata") as any);
    return new Promise((resolve, reject) => {
      if (ossData !== null && new Date(ossData.Expiration) > new Date()) {
        this.ossClient.accessKeyId = ossData.AccessKeyId;
        this.ossClient.accessKeySecret = ossData.AccessKeySecret;
        this.ossClient.stsToken = ossData.SecurityToken;
        this.ossClient.bucket = this.ossComPath;
        resolve(200);
      } else {
      // 如果本地oss key已过期,再向后端获取
        getPublicUpOssSTS().then(
          (res: any) => {
            let json = JSON.parse(JSON.stringify(res.data));
            this.ossClient.accessKeyId = json.AccessKeyId;
            this.ossClient.accessKeySecret = json.AccessKeySecret;
            this.ossClient.stsToken = json.SecurityToken;
            this.ossClient.bucket = this.ossComPath;
            localStorage.setItem("ossdata", JSON.stringify(json));
            resolve(200);
          },
          () => {
            reject(400);
          }
        );
      }
    });
  }
  // 文件成功添加在el-upload时触发的钩子
  onChangeFileValid(file) {
    let xls = file.name.split(".").pop();
    if (["jpg", "png"].includes(xls)) {
    	// 每添加一个文件,就push到 fileList集合中
       this.fileList.push(file);
    } else {
      (this.$refs.modelFormId as any).clearFiles();
      this.$message.error("文件只能上传.jpg或.png的文件!");
    }
    return false;
  }
  // 
// 删除上传的文件
  handleRemove(file, fileList) {
    this.fileList = fileList;
  }
  handlePictureCardPreview(file) {
    this.dialogImageUrl = file.url;
    this.dialogVisible = true;
  }
}
</script>

你可能感兴趣的:(应用场景)