vue“纯前端“ 将文件上传到阿里云 OSS 存储(开箱即用)

import { getPolicy } from “这个接口让后端给 获取oss各种信息的”;
import {  ElLoading } from “element-plus”;
function useOssUpload() {
  const aliOssUpload = async (fileName, file, bucket) => {
    const { data } = await getPolicy({ bucket });
// 创建 FormData 对象来构建 POST 请求的 Body
    const formData = new FormData();
    formData.append(‘key’, `${data.dir}${fileName}`);  // 根据实际情况调整 key 的格式
    formData.append(‘policy’, data.policy);
    formData.append(‘OSSAccessKeyId’, data.accessid);
    formData.append(‘success_action_status’, ‘200’);  // 设置成功状态码
    formData.append(‘signature’, data.signature);
    formData.append(‘file’, file);  // 实际要上传的文件
   const loadingInstance = ElLoading.service({
    fullscreen: true,
    lock: true,
    text: “正在上传中,请耐心稍等”
  });
    // 发起上传请求
    try {
      const response = await fetch(data.host, {
        method: ‘POST’,
        body: formData,
      });
      loadingInstance.close()
      if (response.ok) {
        const url = `${data.host}/${data.dir}${fileName}`;
        console.log(‘Upload success’, url);
        return url;  // 返回文件的 URL
      } else {
        throw new Error(‘Upload failed’);
      }
    } catch (error) {
      loadingInstance.close()
    }
  };

 

  return {
    aliOssUpload
  };
}

 

export default useOssUpload;

///////////////////////////////////////////////////////////useOssUploadAll.ts///////////////////////////////////////////////////////////////////////////////

 

<template>
  <el-upload
    ref=”uploadRef”
    :auto-upload=”autoUpload”
    :http-request=”uploadFile”
    :before-upload=”handleBeforeUpload”
    :on-success=”handleSuccess”
    :show-file-list=”false”
    :multiple=”multiple”
  >
    <template #trigger>
      <el-button>
        <span>{{ buttonText }}</span>
      </el-button>
    </template>
  </el-upload>
</template>
<script setup>
import { ref, defineProps } from “vue”;
import useOssUpload from “@/utils/useOssUploadAll”;
import { getUrl } from “@/api/modules/upload”; //这个接口让后端给 获取下载链接的
import CryptoJS from “crypto-js”; //在阿里云 文件名直接上传会有各种各样的问题,所以这里对文件名进行加密
import { ElMessage } from “element-plus”;
const props = defineProps({
  /**
   * 按钮文本
   * @type {String}
   * @default ‘Upload’
   * @description 显示在上传按钮上的文本内容
   */
  buttonText: {
    type: String,
    default: “Upload”
  },
  /**
   * 是否自动上传
   * @type {Boolean}
   * @default true
   * @description 设置为 true 时,选择文件后会自动开始上传;false 时需要手动触发上传
   */
  autoUpload: {
    type: Boolean,
    default: true
  },
  /**
   * 上传参数
   * @type {Object}
   * @description 上传时需要携带的额外参数,会通过 uploadSuccess 事件返回
   */
  params: {
    type: Object
  },
  /**
   * OSS 存储桶名称
   * @type {String}
   * @description 指定文件上传到哪个 OSS 存储桶
   */
  bucket: {
    type: String
  },
  /**
   * 是否允许多文件上传
   * @type {Boolean}
   * @default false
   * @description 设置为 true 时允许选择多个文件进行上传
   */
  multiple: {
    type: Boolean,
    default: false
  },
  /**
   * 是否使用 MS 加密模式
   * @type {Boolean}
   * @default false
   * @description 设置为 true 时,文件名会使用特定的 MS 加密方式进行加密
   */
  ms: {
    type: Boolean,
    default: false
  }
});
const uploadRef = ref();
const emit = defineEmits([“uploadSuccess”]);
const fileQueue = ref([]);
// 检查文件大小是否超过 10MB
const checkFileSize = file => {
  const MAX_SIZE = 10 * 1024 * 1024; // 10MB
  if (Number(file.size) > MAX_SIZE) {
    ElMessage.error(“文件大小不能超过 10MB”);
    return false;
  }
  return true;
};
// 处理 before-upload 事件
const handleBeforeUpload = file => {
  if (!checkFileSize(file)) {
    return false;
  }
  const timestamp = new Date().getTime();
  const extension = file.name.split(“.”).pop().toLowerCase();
  let str = file.name.substring(0, file.name.lastIndexOf(“.”));
  let encrypted;
  if (props.ms) {
    encrypted = CryptoJS.AES.encrypt(`${timestamp}/${str}`, “secret-key”).toString();
  } else {
    encrypted = CryptoJS.AES.encrypt(file.name, “secret-key”).toString();
  }
  const encodedFileName = encrypted.replace(/\+/g, “!”).replace(/\//g, “~”).replace(/=/g, “茻”);
  const encodedFile = new File([file], encodedFileName + “.” + extension, { type: file.type });
  fileQueue.value.push(encodedFile);
  return true;
};
// 上传文件到 OSS
const uploadFile = async ({ file }) => {
  const { aliOssUpload } = useOssUpload();
  const uploadResults = [];
  try {
    for (let fileItem of fileQueue.value) {
      const url = await aliOssUpload(fileItem.name, new Blob([await fileItem.arrayBuffer()]), props.bucket);
      uploadResults.push({ url, name: fileItem.name });
    }
    fileQueue.value = [];
    return uploadResults;
  } catch (error) {
    return Promise.reject(error);
  }
};
// 处理上传成功事件
const handleSuccess = async response => {
  const processedResults = await Promise.all(
    response.map(async item => {
      if (props.bucket === “aaf-shenzhen-file”) {
        const { data } = await getUrl({ url: item.url });
        return { url: data, name: item.name };
      }
      return { url: item.url, name: item.name };
    })
  );
  // 传递所有处理后的结果和原始文件信息
  emit(“uploadSuccess”, {
    response: processedResults,
    file: response[0], // 当前上传的文件对象
    files: response, // 所有已上传的文件列表
    …props.params
  });
};
</script>
<style scoped></style>
///////////////////////////////////////////elmBtnOssUpload.vue///////////////////////////////////////////////////////////
使用
 <FileUpload
            buttonText=”上传文件”
            :params=”{}”
            bucket=”public-aaf-shenzhen-file”
            :multiple=”false”
            @uploadSuccess=”handleUploadSuccess”
          />
//////////////////////////////////////////

如果要预览功能 也是让后端给接口

// 获取文件预览链接
export const getFilePreviewUrl = params => {
  return http.get<Upload.ResFileUrl>(PORT1 + `/file/ossFile/getFilePreviewUrl?fileId=${params.id}`);
};
const preview=async(row)=>{
  const {data}=await getFilePreviewUrl({id:row.id})
  window.open(data,’_blank’)
}
作为前端只需要获取data打开就好了   本来这勾八功能就应该后端搞 如果他连接口都不出的话 建议吊一顿 再找领导吊他一顿

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注