vue + elementUI (el-upload) + 阿里oss 上传文件(视频,图片等) 并 显示上传进度条

先来看上传效果

在这里插入图片描述

1.先安装alioss

npm i ali-oss --save

2.安装完事之后,进行引入并进行oss的初始化,这里把初始化和后面用到的UUID生成规则放在一起,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。
 */
export function client(data) {//data后端提供数据
  return new OSS({
    region: data.region,
    accessKeyId: data.accessKeyId,
    accessKeySecret:  data.accessKeySecret,
    bucket: data.bucket
  })
}

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

3.组件内使用

oss文件上传分为Blob数据上传 和 断点上传也就是分片上传,这里的展示是分片上传功能,关于文件上传官方文档请参阅 上传文件
(1)html部分

<template>
  <div class="content">
    <el-upload
      action
      :http-request="Upload"
      :before-upload="beforeAvatarUpload"
      :on-preview="handlePreview"
      :before-remove="beforeRemove"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :on-exceed="handleExceed"
      drag
      :limit="limit"
      :file-list="fileList"
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">
        将文件拖到此处,或
        <em>点击上传</em>
      </div>
      <div slot="tip" class="el-upload__tip">上传文件大小不能超过 1G</div>
    </el-upload>

    <el-progress
      v-show="showProgress"
      :text-inside="true"
      :stroke-width="15"
      :percentage="progress"
    ></el-progress>
  </div>
</template>

(2)js部分

import { client , getFileNameUUID  } from "@/utils/ali-oss"; //前面的ali-js文件内的两个封装函数
import { getAliOSSConfig } from "@/api/admin";  //请求后台的接口拿Ali-OSS数据
export default {
  name: "Upload",
  props: {
    limit: {
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      fileList: [],//文件列
      showProgress: false,//进度条的显示
      dataObj: {}, //存签名信息
      progress: 0 //进度条数据
    };
  },
  methods: {
    // 文件超出个数限制时的钩子
    handleExceed(files, fileList) {
      this.$message.warning(`每次只能上传 ${this.limit} 个文件`);
    },
    // 点击文件列表中已上传的文件时的钩子
    handlePreview(file) {},
    // 删除文件之前的钩子
    beforeRemove(file, fileList) {
      return this.$confirm(`确定移除 ${file.name}?`);
    },
    // 文件列表移除文件时的钩子
    handleRemove(file, fileList) {},
    // 文件上传成功时的钩子
    handleSuccess(response, file, fileList) {
      this.fileList = fileList;
    },
    //文件上传前的校验
    beforeAvatarUpload(file) {
      const isLt100M =
        file.size / 1024 / 1024 > 10 && file.size / 1024 / 1024 < 1024;
      const isLt30 = file.name.length < 30;
      if (["video/mp4"].indexOf(file.type) == -1) {
        this.$message.error("请上传正确的视频格式");
        return false;
      }
      if (!isLt100M) {
        this.$message.error("上传视频大小要在10MB~1GB之间哦!");
        return false;
      }
      if (!isLt30) {
        this.$message.error("上传视频文件名称长度必须要小于30个文字哦!");
        return false;
      }
	  // 请求后台接口拿配置参数
      return new Promise((resolve, reject) => {
        getAliOSSConfig()
          .then(response => {
            this.dataObj = response.data; //接口返回配置参数
            console.log(response.data);
            resolve(true);
          })
          .catch(err => {
            console.log(err);
            reject(false);
          });
      });
    },
    // http-request属性来覆盖默认的上传行为(即action="url"),自定义上传的实现 
    Upload(file) {
      const that = this;
      async function multipartUpload() {
        let temporary = file.file.name.lastIndexOf(".");
        let fileNameLength = file.file.name.length;
        let fileFormat = file.file.name.substring(
          temporary + 1,
          fileNameLength
        );
        let fileName = getFileNameUUID() + "." + fileFormat; 
        client(that.dataObj)
          .multipartUpload(`videoTest/${fileName}`, file.file, {
            progress: function(p) {
              //p进度条的值
              console.log(p);
              that.showProgress = true;
              that.progress = Math.floor(p * 100);
            }
          })
          .then(result => {
            //上传成功返回值,可针对项目需求写其他逻辑
            console.log(result);
          })
          .catch(err => {
            console.log("err:", err);
          });
      }
      multipartUpload();
    }
  }
};
</script>

(3)至此以上内容就完成了文件分片上传并显示进度条,遇到问题参阅如下:

出现问题
上传出现跨域问题,或者出现分片上传 最后一个请求报错 One or more of the specified parts could not be found or the specified entity tag might not have matched the part’s entity tag 错误
解决办法
在阿里云oss控制台 基础设置 > 跨域规则设置 > 编辑规则 “允许 Headers”添加 ‘ * ’ 即可解决跨域问题, “暴露 Headers” 中增加 ‘ ETag ’ 即可解决分片上传最后一个请求报错报错问题
在这里插入图片描述

出现问题
怎么设置callback函数,如何在URL中携带参数,关于callback的官方文档
解决办法
在client.multipartUpload参数中,例如:

callback: {
  url: 'http://oss-demo.aliyuncs.com:23450',
  host: 'oss-cn-hangzhou.aliyuncs.com',
  body: 'bucket=${bucket}&object=${object}&var1=${x:var1}',
  contentType: 'application/x-www-form-urlencoded',
  customValue: {
    var1: 'value1',
    var2: 'value2',
  },
},
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你好!YOYO

你的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值