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>