使用腾讯云对象云存储实现大文件上传,下载

262 阅读2分钟

使用腾讯云对象云存储实现大文件上传

网站: www.yuque.com/yejianhua-6…

引入模块:import COS from "cos-js-sdk-v5";

一、文件上传

  1. 大文件使用云存储上传,小文件正常调接口上传
<el-form-item prop="publisher" style="margin-bottom: 0">
                      <el-upload
                        :http-request="handleUploadFile"
                        class="upload-demo"
                        v-model:file-list="fileList"
                        :before-upload="beforeUpload"
                        :on-progress="handleProgress"
                        :on-success="handleFileSuccess"
                        :before-remove="beforeFileRemove"
                        :on-remove="handleFileRemove"
                        :on-change="handleFileChange"
                      >
                        <el-button type="primary" style="margin-top: 10px"
                          >Click to upload
                        </el-button>
                        <template #tip>
                          <div class="fileList" v-if="originFileName">
                            <span>{{ originFileName }}</span>
                          </div>
                          <div class="el-upload__tip">
                            <el-progress
                              v-if="progress"
                              :percentage="percentage"
                            />
                            Attached Files [.doc, .zip, .docx, .pdf, .gif, .txt,
                            .jpg, .jpeg, .png, .tiff, .tif]
                          </div>
                        </template>
                      </el-upload>
                    </el-form-item>
                    
  1. 文件上传方法
async function handleUploadFile(options: UploadRequestOptions): Promise<any> {
  if (!isExeced50M.value || !accessDiscussion.value) {
    console.log("小于50");
    // 小于50M
    const { data } = await discussionUpload(options.file);
    // 保存文件的 ID 到文件对象的 id 属性中
    options.file.id = data.content.fileId;
    // ruleForm.fileId.push(data.content.fileId);
  } else {
    console.log("大于50");
    // accessDiscussion 为true,支持腾讯云上传
    const fileSuffix = options.file.name.substring(
      options.file.name.lastIndexOf(".")
    );
    fileKey.value = guid() + fileSuffix;
    originFileName.value = options.file.name;
    // 超过50m的大文件,使用腾讯云对象云存储
    upFileLoad1({
      type: 1,
    }).then((res) => {
      let cos = new COS({
        getAuthorization: function (options, callback) {
          callback({
            //腾讯云账号上传信息
            TmpSecretId: res.data.secretId,
            TmpSecretKey: res.data.secretKey,
            SecurityToken: res.data.sessionToken,
            // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
            StartTime: res.data.startTime, // 时间戳,单位秒,如:1580000000
            ExpiredTime: res.data.expiredTime, // 时间戳,单位秒,如:1580000000
          });
        },
      });
      progress.value = true;

      cos.putObject(
        {
          Bucket: bucket.value /* 填入您自己的存储桶,必须字段 */,
          Region: region.value /* 存储桶所在地域,例如ap-beijing,必须字段 */,
          Key:
            "discussion/" +
            fileDir.value +
            fileKey.value /* 存储在桶里的对象键(例如1.jpg,a/b/test.txt),必须字段 */,
          Body: options.file /* 必须,上传文件对象,可以是input[type="file"]标签选择本地文件后得到的file对象 */,
          onProgress: function (progressData) {
            percentage.value = progressData.percent * 100;
          },
        },
        function (err, data) {
          if (err) {
            console.log("上传失败", err);
            // $("#progressBarFormGroup").hide()
            // layer.msg('Upload Failed');
          } else {
            filePath.value = fileDir.value + fileKey.value;
          }
        }
      );
    });
  }
}

upFileLoad1是后端接口,调用该接口获取相应数据,如:secretId,secretKey,sessionToken,startTime,expiredTime等 另外,还要从其他接口获取到bucket,region,fileDir等数据,如下:

const checkDiscussionSingleDatas = async () => {
  ruleForm.message = "";
  ruleForm.fileId = [];
  ruleForm.selectedFiles = [];
  allDatas.value.articleFiles = [];
  checkDiscussionSingle({ id: props.id }).then((res) => {
    allDatas.value = res.data.content;
    ruleForm.discussionId = res.data.content.discussionId;
    // 获取相应的数据 -------------------------------------------
    bucket.value = res.data.content.bucket;
    fileDir.value = res.data.content.fileDir;
    region.value = res.data.content.region;
    // originFileName.value = res.data.content.originFileName;
  });
};

效果:

image.png

二、文件下载

 <el-row class="listKuang">
                        <a
                          target="_blank"
                          style="color: rgb(57, 57, 141)"
                          @click.prevent="fetchDownloadUrl(items)"
                          >{{ items.originFileName }}</a
                        >
                      </el-row>

下载方法:

const fetchDownloadUrl = (item) => {
  getDownloadUrl(item, (url) => {
    /*************  ✨ Codeium Command ⭐  *************/
    /**
     * 获取临时密钥
     * @param {object} options
     * @param {function} callback
     * @returns {void}
     */
    /******  a0675bb7-92ec-4f41-9c29-335050793edf  *******/ if (url) {
      window.open(url, "_blank");
    }
  });
};

const getDownloadUrl = (item, callback) => {
  let cos = new COS({
    getAuthorization: function (options, callback) {
      upFileLoad1({
        type: 1,
      }).then((res) => {
        callback({
          TmpSecretId: res.data.secretId,
          TmpSecretKey: res.data.secretKey,
          SecurityToken: res.data.sessionToken,
          StartTime: res.data.startTime,
          ExpiredTime: res.data.expiredTime,
        });
      });
    },
  });

  cos.getObjectUrl(
    {
      Bucket: bucket.value,
      Region: region.value,
      Key: "discussion/" + item.cosFileName,
      Sign: true, // 生成带签名的 URL
      Expires: 3600, // URL 有效期,单位为秒
    },
    function (err, data) {
      if (err) {
        console.log("获取下载链接失败", err);
        callback("");
      } else {
        callback(data.Url);
      }
    }
  );
};