zoukankan      html  css  js  c++  java
  • 上传文件到oss和下载

    <template>
      <el-upload
        ref="single-upload"
        :action="uploadConf.action"
        :multiple="false"
        :headers="uploadConf.headers"
        :data="uploadConf.data"
        :before-upload="onBeforeUpload"
        :on-progress="onProgress"
        :on-success="onSuccess"
        :show-file-list="false"
      >
        <slot></slot>
      </el-upload>
    </template>
    
    <script>
    import getUploadSign from "@/api";
    import generateId from 'nanoid/generate';
    
    // 随机文件名
    export default {
      name: "CSingleUpload",
      components: {},
      props: {
        accept: {
          type: Array,
          default: () => []
        },
        maxFileSize: {
          type: Number,
          default: 20
        },
        files: {
          type: Array,
          default: () => []
        }
      },
      data() {
        return {
          fileList: [],
          uploadConf: {
            action: "",
            headers: {},
            data: {},
            fileList: []
          },
          fileObj: null,
        };
      },
      methods: {
        // 上传前拦截
        async onBeforeUpload(file) {
          const { size, type, name, uid } = file;
          const oldName = name;
          const nameArr = oldName.split('.');
          const fileName = nameArr[0] + '-' + generateId('0123456789qwertyuiopasdfghjklzxcvbnm', 15) + '.' + nameArr[1];
    
          // 判断文件类型
        //   const isFileType = this.accept.some(accept => accept === type);
        //   if (!isFileType) {
        //     this.$message.warning(`该文件(${oldName})类型(${type})不支持`);
        //     return Promise.reject();
        //   }
    
          // 判断文件大小
          const KB = size / 1024;
          const MB = KB / 1000;
          if (MB > this.maxFileSize) {
            let unit = `${this.maxFileSize}m`;
            if (this.maxFileSize < 1) {
              unit = `${Math.floor(this.maxFileSize * 1000)}kb`;
            }
            this.$message.warning(`该文件(${oldName})大小已超过限制(${unit})`);
            return Promise.reject();
          }
    
          // 请求签名
          const sign = await getUploadSign({ dir: type.split('/')[0], key: fileName });
          
          // 显示上传对象
          this.fileObj = {
            type,
            size,
            uid,
            oldName,
            name: fileName,
            url: (window.URL || window.webkitURL).createObjectURL(file),
            ossUrl: `${sign.host}/${sign.dir}${fileName}`,
            progress: 0,
            isUpload: false
          };
    
          // 填充签名参数
          this.uploadConf.data = {
            key: `${sign.dir}${fileName}`,
            policy: sign.policy,
            OSSAccessKeyId: sign.accessid,
            success_action_status: 200,
            signature: sign.signature,
            callback: sign.callback,
          };
          this.uploadConf.action = sign.host;
          this.uploadConf.headers = {
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "GET, POST"
          };
          // return Promise.reject();
        },
    
        // 更新文件上传进度
        onProgress(event) {
          const { percent } = event;
          this.$emit("on-progress", percent);
        },
    
    
        // 更新文件上传成功状态
        onSuccess(response, file) {
          this.$emit('successCBK', this.fileObj.ossUrl, this.fileObj);
        },
      }
    };
    </script>
    
    <style lang="less" scoped>
    </style>
    

      

    这种下载文件的方式兼容性比较好,一般不会出现跨域问题,如果使用的是axios封装的方法下载可能跨域。

    export function downloadFile2(url, filename) {
      /**
    * 下载文件
    * 原理:通过获取文件内容转译为二进制,传给创建a标签下载
    * @param url  文件地址url
    * @param filename 下载保存的名字
    */
        var downloadFileBya = function (fileName, content) {
          var aLink = document.createElement('a');
          var blob = new Blob([content]);
          var evt = document.createEvent("MouseEvents");
          evt.initEvent("click", true, true);
          if (fileName) {
            aLink.download = fileName;
          }
          aLink.target = "_blank";
          aLink.href = URL.createObjectURL(blob);
          aLink.dispatchEvent(evt);
        }
        // 拿文件的名字
        var fileNameFromHeader = function (disposition) {
          if (disposition) {
            let index = disposition.lastIndexOf("/");
            return decodeURIComponent(disposition.substring(index + 1, disposition.length));
          }
          return "undefine_file";
        }
    
        var xhr = new XMLHttpRequest();
        xhr.withCredentials = false;
        xhr.responseType = "blob";
        xhr.open('GET', url, true);
        xhr.onload = function () {
          if (this.status == 200) {
            // var blob = this.response;
            var donwloadName = filename != undefined ? filename : fileNameFromHeader(xhr.responseURL);
            downloadFileBya(donwloadName, xhr.response);
          } else {
            console.error("请求下载文件错误,请求错误码:" + this.status);
            return false;
          }
        }
        xhr.send();
    }
    

      

  • 相关阅读:
    linux-磁盘挂载脚本
    VSCode插件
    数据模拟--Mock.js
    Vue学习笔记之组件
    Vue学习笔记之动画
    Echarts柱状图常用配置项
    Vue学习笔记之总体结构
    JSON数据格式开发规范
    苹果电脑和手机浏览器的区分
    二维码生成插件(jquery.qrcode.js)说明文档
  • 原文地址:https://www.cnblogs.com/lujunan/p/11243145.html
Copyright © 2011-2022 走看看