vue3调用baidu,sdk上传到百度云,带STS验证

1.使用的是elementPlus Upload组件,自定义上传调用uploadFn方法

<el-upload
    ref="upload"
    :action="action"
    :on-success="handleAvatarSuccess"
    :auto-upload="true"
    :http-request="uploadFn"
    :show-file-list="false"
    :before-upload="beforeAvatarUpload"
  >
    <el-progress v-if="isStart" type="circle" :percentage="percentageValue" />
    <slot v-else />
  </el-upload>

2. 下载百度官方提供的sdk并在页面引入

npm install @baiducloud/bos-uploader
import { BosClient } from "@baiducloud/sdk"

3. 创建实例对象,注意要在uploadFn外面创建

const client = new BosClient({})

4.请求后台接口获取上传需要的参数,ak,sk,token,bucket,上传成功之后并不会返回对应的URL,需要通过 generatePresignedUrl获取对应的URL。

const isStart = ref(false)
const uploadFn: UploadRequestHandler = async (option) => {
  isStart.value = true
  const { data } = await workbenchBosInfoApi()
  const config = {
    endpoint: "https://bj.bcebos.com", //传入Bucket所在区域域名
    credentials: {
      ak: data.ak, //您的AccessKey
      sk: data.sk //您的SecretAccessKey
    },
    sessionToken: "data.session_token" // STS服务器下发的sessionToken
  }
  client.config = config
  const bucket = data.bucket_name
  const key = option.file.name
  client.config.sessionToken = data.session_token
  console.log(client)
  try {
    await client.putObjectFromBlob(bucket, key, option.file)
    const url = client.generatePresignedUrl(data.bucket_name, key, Math.floor(Date.now() / 1000), -1)
    return url
  } catch (error) {
    console.log(error)
    isStart.value = false
  }
}

5. 因为 @baiducloud/bos-uploader没有提供TS支持,需要在全局.d.ts文件中进行声明

declare module "@baiducloud/sdk"

6. Upload完整代码

<template>
  <el-upload
    ref="upload"
    :action="action"
    :on-success="handleAvatarSuccess"
    :auto-upload="true"
    :http-request="uploadFn"
    :show-file-list="false"
    :before-upload="beforeAvatarUpload"
  >
    <el-progress v-if="isStart" type="circle" :percentage="percentageValue" />
    <slot v-else />
  </el-upload>
</template>
<script setup lang="ts">
import { ElMessage } from "element-plus"
import type { UploadProps, UploadRequestHandler } from "element-plus"
import { workbenchBosInfoApi } from "@/api/copilot/index" // 服务端获取key
import { BosClient } from "@baiducloud/sdk"
interface Props {
  limit?: number
  size?: number
  action?: string
}
const props = withDefaults(defineProps<Props>(), {
  size: 500,
  action: ""
})

const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  if (rawFile.type !== "image/jpeg" && rawFile.type !== "image/png" && rawFile.type !== "image/gif") {
    ElMessage.error("请选择图片!")
    return false
  } else if (rawFile.size / 1024 / 1024 > props.size) {
    ElMessage.error(`选择的图片大小不能超过${props.size}MB!`)
    return false
  }
  return true
}

const emits = defineEmits<{
  (e: "upload-success", data: any): void
}>()

const handleAvatarSuccess: UploadProps["onSuccess"] = (response) => {
  isStart.value = false
  if (response) {
    emits("upload-success", response)
  }
}
type EVT = {
  loaded: number
  total: number
  lengthComputable: boolean
}
const client = new BosClient({})
const percentageValue = ref<number>(0)
client.on("progress", function (evt: EVT) {
  console.log(evt)
  // 监听上传进度
  if (evt.lengthComputable) {
    // 添加您的代码
    percentageValue.value = parseInt((evt.loaded / evt.total) * 100 + "")
    console.log("上传中,已上传了" + percentageValue.value + "%")
  }
})
const isStart = ref(false)
const uploadFn: UploadRequestHandler = async (option) => {
  isStart.value = true
  const { data } = await workbenchBosInfoApi()
  const config = {
    endpoint: "https://bj.bcebos.com", //传入Bucket所在区域域名
    credentials: {
      ak: data.ak, //您的AccessKey
      sk: data.sk //您的SecretAccessKey
    },
    sessionToken: "data.session_token" // STS服务器下发的sessionToken
  }
  client.config = config
  const bucket = data.bucket_name
  const key = option.file.name
  client.config.sessionToken = data.session_token
  console.log(client)
  try {
    await client.putObjectFromBlob(bucket, key, option.file)
    const url = client.generatePresignedUrl(data.bucket_name, key, Math.floor(Date.now() / 1000), -1)
    return url
  } catch (error) {
    console.log(error)
    isStart.value = false
  }
}
</script>

 

posted @ 2024-04-16 15:29  敲敲碰碰  阅读(73)  评论(0编辑  收藏  举报