前端采用存储桶上传文件

300 阅读2分钟

1,安装依赖

cos-js-sdk-v5,spark-md5

2,页面逻辑代码

  2.1,上传组件

<el-form-item label="相关资质:" prop="qualificationsPath">
  <el-upload
    class="avatar-uploader"
    action
    :http-request="uploadRequest"
    :show-file-list="false"
    :on-success="
      (response, file, fileList) =>
        handleUploadSuccess(response, file, fileList, 'qualificationsPath')
    "
  >
    <img
      v-if="userInfo.qualificationsPath"
      :src="userInfo.qualificationsPath"
      class="avatar"
    />
    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
  </el-upload>
</el-form-item>

  2.2,文件上传请求

// 文件上传
uploadRequest(option) {
  let that = this;
  tencentCos.uploadFile(
    option.file,
    (data, status) => {
      if (status === "success") {
        option.onSuccess(data);
        console.log("callback--->", data);
      }
    },
    function(e) {
      that.$set(that.fileList[i], "progress", e * 100);
    }
  );
  // .then(file => {
  //   console.log(file);
  // });
},

3,引入js代码

import axios from "axios";
import COS from "cos-js-sdk-v5";
import SparkMD5 from "spark-md5";
import CommonApis from "@/apis/common";
var key = "";
// 配置
const cosConfig = {
  Bucket: "",
  Region: "ap-beijing"
};

// 获得文件md5
function getFileMD5(file, callback) {
  // 声明必要的变量
  const fileReader = new FileReader();
  // 文件每块分割2M,计算分割详情
  const chunkSize = 2 * 1024 * 1024;
  const chunks = Math.ceil(file.size / chunkSize);
  let currentChunk = 0;

  // 创建md5对象(基于SparkMD5)
  const spark = new SparkMD5();

  // 每块文件读取完毕之后的处理
  fileReader.onload = function(e) {
    // 每块交由sparkMD5进行计算
    spark.appendBinary(e.target.result);
    currentChunk++;

    // 如果文件处理完成计算MD5,如果还有分片继续处理
    if (currentChunk < chunks) {
      loadNext();
    } else {
      callback(spark.end());
    }
  };

  // 处理单片文件的上传
  function loadNext() {
    const start = currentChunk * chunkSize;
    const end = start + chunkSize >= file.size ? file.size : start + chunkSize;

    fileReader.readAsBinaryString(file.slice(start, end));
  }

  loadNext();
}
const files = {
  //base64转blob文件流
  convertBase64UrlToBlob(base64) {
    let urlData = base64.dataURL;
    let type = base64.type;
    let bytes = null;
    if (urlData.split(",").length > 1) {
      //是否带前缀
      bytes = window.atob(urlData.split(",")[1]); // 去掉url的头,并转换为byte
    } else {
      bytes = window.atob(urlData);
    }
    // 处理异常,将ascii码小于0的转换为大于0
    let ab = new ArrayBuffer(bytes.length);
    let ia = new Uint8Array(ab);
    for (let i = 0; i < bytes.length; i++) {
      ia[i] = bytes.charCodeAt(i);
    }
    return new Blob([ab], { type: type });
  },
  exportFile(url, params) {
    let unNormalAxiosInstance = axios.create({
      headers: {
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
        Authorization: localStorage.getItem("TOKEN") || ""
      }
    });
    return unNormalAxiosInstance.get(url, {
      params: {
        params: encodeURI(JSON.stringify(params))
      },
      responseType: "blob"
    });
  },
  // 小文件直接上传-通过putObject上传
  uploadFile(file, callback, progressBc) {
    CommonApis.getCOSAuth().then(res => {
      const authdata = res.data;
      cosConfig.Bucket = authdata.bucketName;
      // 初始化实例
      let cos = new COS({
        getAuthorization: async function(options, callback) {
          /**
           * 签名计算放在前端会暴露 SecretId 和 SecretKey
           * 我们把签名计算过程放在后端实现,前端通过 ajax 向后端获取签名结果
           * 正式部署时请再后端加一层自己网站本身的权限检验。
           * 异步获取临时密钥
           */
          const auth = {
            TmpSecretId: authdata.tmpSecretId,
            TmpSecretKey: authdata.tmpSecretKey,
            startTime: authdata.startTime,
            XCosSecurityToken: authdata.sessionToken,
            ExpiredTime: authdata.expiredTime // 在ExpiredTime时间前,不会再次调用getAuthorization
          };
          callback(auth);
        }
      });
      // 得到md5码
      getFileMD5(file, md5 => {
        // 存储文件的md5码
        file.md5 = md5;
        if (file.name) {
          const subfix = file.name.substr(file.name.lastIndexOf("."));
          key = file.md5 + subfix;
        } else {
          key = new Date().getTime() + ".jpg";
        }
        cos.putObject(
          {
            Bucket: cosConfig.Bucket,
            Region: cosConfig.Region,
            StorageClass: "STANDARD",
            Key: key,
            Body: file,
            onProgress: function(progressData) {
              progressBc(progressData.percent);
            }
          },
          (err, data) => {
            if (err && err.error) {
              // 请求失败
              callback(err, "error");
            } else if (err) {
              // 请求出错
              callback(err, "error");
            } else {
              callback(data, "success");
              // 上传成功
            }
          }
        );
      });
    });
  }
};

export default files;