前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >腾讯云 COS 文件 Web 直传

腾讯云 COS 文件 Web 直传

原创
作者头像
dandelion1990
发布2024-01-03 23:22:51
2730
发布2024-01-03 23:22:51
举报

主要参考以下文档与代码

后端 STS 服务

接口提供临时密钥和 token,服务端代码如下:

代码语言:go
复制
package main

import (
	"encoding/json"
	"log"
	"net/http"
	"os"
	"strconv"
	"time"

	"github.com/joho/godotenv"
	sts "github.com/tencentyun/qcloud-cos-sts-sdk/go"
)

const DefaultCredExpireTime = 600 // seconds

var (
	appId  string
	bucket string
	region string
	stsClient *sts.Client
	credOpts  *sts.CredentialOptions
	stsExpireTime int
)

type Credentials struct {
	TmpSecretId  string `json:"tmpSecretId"`
	TmpSecretKey string `json:"tmpSecretKey"`
	SessionToken string `json:"sessionToken"`
}

type CredentialsResp struct {
	Credentials Credentials `json:"credentials"`
	StartTime   int64       `json:"startTime"`
	ExpiredTime int64       `json:"expiredTime"`
}

func init() {
	err := godotenv.Load()
	if err != nil {
		log.Fatal(err)
	}

	appId = os.Getenv("COS_APPID")
	bucket = os.Getenv("COS_BUCKET")
	region = os.Getenv("COS_REGION")
	secretId := os.Getenv("COS_SECRET_ID")
	secretKey := os.Getenv("COS_SECRET_KEY")
	stsExpireTime, err = strconv.Atoi(os.Getenv("STS_EXPIRE_TIME"))
	if err != nil {
		log.Printf("read enviroment `STS_EXPIRE_TIME` error: %v\n", err)
		log.Printf("set `STS_EXPIRE_TIME` to default %v", DefaultCredExpireTime)
		stsExpireTime = DefaultCredExpireTime
	}

	stsClient = sts.NewClient(
		secretId,
		secretKey,
		nil,
	)

	credOpts = &sts.CredentialOptions{
		DurationSeconds: int64(stsExpireTime),
		Region:          region,
		Policy: &sts.CredentialPolicy{
			Statement: []sts.CredentialPolicyStatement{
				{
					Action: []string{
						"name/cos:PostObject",
						"name/cos:PutObject",
						"name/cos:InitiateMultipartUpload",
						"name/cos:ListMultipartUploads",
						"name/cos:ListParts",
						"name/cos:UploadPart",
						"name/cos:CompleteMultipartUpload",
					},
					Effect: "allow",
					Resource: []string{
						"qcs::cos:ap-guangzhou:uid/" + appId + ":" + bucket + "/*",
					},
					Condition: map[string]map[string]interface{}{},
				},
			},
		},
	}
}

func getCredentialsHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
	w.Header().Set("Access-Control-Allow-Headers", "*")

	res, err := stsClient.GetCredential(credOpts)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	resp := CredentialsResp{
		Credentials: Credentials{
			TmpSecretId:  res.Credentials.TmpSecretID,
			TmpSecretKey: res.Credentials.TmpSecretKey,
			SessionToken: res.Credentials.SessionToken,
		},
		StartTime:   time.Now().Unix(),
		ExpiredTime: time.Now().Add(time.Duration(stsExpireTime) * time.Second).Unix(),
	}
	err = json.NewEncoder(w).Encode(resp)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}

func main() {
	log.Println("RunStsServer starts...")
	http.HandleFunc("/credentials", getCredentialsHandler)
	http.ListenAndServe(":8080", nil)
}

通过调用接口就可以获得临时密钥

代码语言:bash
复制
curl "http://127.0.0.1:8080/credentials"

因为要在 Web 调用,因此需要设置允许跨域请求

代码语言:go
复制
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "*")

Web 直传 demo

代码语言:vue
复制
<template>
  <div>
    <input type="file" @change="uploadImage" ref="imageInput" />
    <button @click="submitImage">Upload Image</button>
  </div>
</template>
  
<script>
import COS from 'cos-js-sdk-v5';

export default {
  data() {
    return {
      imageFile: null,
      imageUrl: null,
      cos: null,
    };
  },
  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 bucket = ${bucket};
      const region = ${region};
      const key = `images/${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.imageUrl = `https://${bucket}.cos.${region}.myqcloud.com/${key}`;
            console.log("Image uploaded successfully. URL:", this.imageUrl);
            alert("Image uploaded successfully.");
            this.$refs.imageInput.value = null;
            this.imageFile = null;
          }
        }
      );
    },
  },
};
</script>

点击对应按钮即可上传图片至 COS

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 后端 STS 服务
  • Web 直传 demo
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档