上一篇讲了如何通过 Web 直传文件到 COS,在其基础上介绍上传后如何下载文件
后端 STS 服务
首先后端的 STS 服务需要改造一下,增加查询下载 URL 的权限
代码语言:go复制{
Action: []string{
// 下载操作
"name/cos:GetObject",
},
Effect: "allow",
Resource: []string{
"qcs::cos:ap-guangzhou:uid/" appId ":" bucket "/*",
},
Condition: map[string]map[string]interface{}{},
},
其他权限列表请可以看:COS API 授权策略使用指引
前端 Demo 改造
参考Javascript SDK,上传后通过 SDK 得到访问 URL,可以在页面展示或者下载
代码语言:vue复制<template>
<div>
<div>
<input type="file" @change="uploadImage" ref="imageInput" />
<button @click="submitImage">Upload Image</button>
<button v-if="imageUrl" @click="downloadImage">Download Image</button>
</div>
<div>
<img v-if="imageUrl" :src="imageUrl" alt="Description of image ">
</div>
</div>
</template>
<script>
import COS from 'cos-js-sdk-v5';
const bucket = ${bucket};
const region = ${region};
export default {
data() {
return {
imageFile: null,
cos: null,
imageUrl: null,
imageKey: null,
tmpSecretId: "",
tmpSecretKey: "",
sessionToken: "",
};
},
methods: {
uploadImage(event) {
this.imageFile = event.target.files && event.target.files[0];
},
submitImage() {
if (!this.imageFile) {
alert("Please choose an image to upload.");
return;
}
this.initCOS();
this.uploadToCOS();
},
initCOS() {
this.cos = new COS({
getAuthorization: function (options, callback) {
const url = 'http://${host}:8080/credentials'
const xhr = new XMLHttpRequest()
let data = null
let credentials = null
xhr.open('GET', url, true)
xhr.onload = function (e) {
try {
data = JSON.parse(e.target.responseText);
credentials = data.credentials;
} catch (e) {
console.log(e)
}
if (!data || !credentials) {
return console.error('credentials invalid:n' JSON.stringify(data, null, 2))
}
callback({
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
SecurityToken: credentials.sessionToken,
StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000
})
}
xhr.send();
}
})
},
uploadToCOS() {
const key = `test/${Date.now()}_${this.imageFile.name}`;
this.cos.uploadFile(
{
Bucket: bucket,
Region: region,
Key: key,
StorageClass: "STANDARD",
Body: this.imageFile,
},
(err) => {
if (err) {
console.error("Error uploading image:", err);
alert("Error uploading image.");
} else {
this.imageKey = key;
this.getImageUrl()
alert("Image uploaded successfully.");
this.$refs.imageInput.value = null;
this.imageFile = null;
}
}
);
},
getImageUrl() {
let that = this
this.cos.getObjectUrl({
Bucket: bucket,
Region: region,
Key: this.imageKey,
}, function (err, data) {
if (err) return console.log(err);
/* 通过指定 response-content-disposition=attachment 实现强制下载 */
const downloadUrl = data.Url (data.Url.indexOf('?') > -1 ? '&' : '?') 'response-content-disposition=attachment';
/* 可拼接 filename 来实现下载时重命名 */
/* downloadUrl = ';filename=myname'; */
// (推荐使用 window.open()方式)这里是新窗口打开 url,如果需要在当前窗口打开,可以使用隐藏的 iframe 下载,或使用 a 标签 download 属性协助下载
that.imageUrl = downloadUrl
console.log("Image uploaded successfully. URL:", that.imageUrl);
})
},
downloadImage() {
const link = document.createElement("a");
link.href = this.imageUrl;
link.download = this.imageUrl.split("/").pop();
link.click();
},
},
};
</script>