后端返回预签名url,前端直传腾讯云cos


前言

最近搞了两天的腾讯云cos服务器上传图片,在网上查了很多文章,大部分都是说的纯前端、纯后端或者是其他语言直传cos,很少有使用后端java生成预签名url,前端element-ui再进行直传cos的文章。使用这种方案既解决了纯前端直传可能会造成密钥泄露的问题,也解决了后端上传cos影响性能的问题。


一、注册腾讯云获取密钥

具体注册流程网上文章很多,自己找找就好了,很简单的。
在这里插入图片描述

二、后端生成签名url

1.导入依赖

<dependency>
   <groupId>com.qcloud</groupId>
    <artifactId>cos_api</artifactId>
    <version>5.6.54</version>
</dependency>

如果导入依赖报错,可以去官网的 ‘产品文档’ 更新最新的依赖:

在这里插入图片描述

2.创建controller

代码如下:

package top.itimmortal.edu.controller;

@RestController
@RequestMapping("/oss")
public class SignDemo { //文件名自行修改

    @GetMapping("/sign")
    public static JSONResult generateCosSignature() {
        // 1 初始化
        COSCredentials cred = new BasicCOSCredentials("你的SecretId", "你的SecretKey");
        // 2 设置的所属地域:我的是https://itimmortal-1319957111.cos.ap-chengdu.myqcloud.com
        ClientConfig clientConfig = new ClientConfig();
        Region region = new Region("ap-chengdu");  //更换为你的所属地域,我这里是成都的
        clientConfig.setRegion(region);

        // 3 生成 cos 客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        // 你存储桶名称
        String bucketName = "itimmortal-1319957111";
        //对象键(Key),使用UUID生成不重复的随机数,然后拼接文件后缀组成你前端上传到cos中的文件名
        String key = UUID.randomUUID() +  ".jpeg";  //33585111-093d-4502-a5ef-d5405ee19f2e.jpeg
        //签名过期时间
        Date expirationTime = new Date(System.currentTimeMillis() + 30 * 60 * 1000);
        // 生成预签名上传 URL
        //示例:https://itimmortal-1319957351.cos.ap-chengdu.myqcloud.com/0d3326e5-2272-4ee0-8445-e0ef5eec98fc.jpeg?sign=q-sign-algorithm%3Dsha1%26q-ak%3DAKIDxu111Pr9GBvUs1111lLm3Dj7PUBjIuXS%26q-sign-time%3D1691402050%3B1691111850%26q-key-time%3D169141150%3B169140111%26q-header-list%3Dhost%26q-url-param-list%3D%26q-signature%3D7d833d12f6e1668e260fa56edd0037f112e68111
        URL url = cosclient.generatePresignedUrl(bucketName, key, expirationTime, HttpMethodName.PUT, new HashMap<>(), new HashMap<>());
        //返回json格式给后端
        return JSONResult.success(url);
    }
}

其实在官网也有,https://cloud.tencent.com/document/product/436/35217,我也是在总结博客去的时候才突然看到的,一直没看到…

三. 前端代码

使用element-ui的el-upload组件,可以在官网copy下来进行修改:

<el-form-item prop="logo" style="width: 400px">
	<!--
	action:上传的地址,
	auto-upload:是否在选取文件后立即进行上传,
	http-request:自定义上传的实现,
	before-upload:上传文件之前的钩子
	-->
   <el-upload
       class="upload-demo"
       action="https://itimmortal-1319957111.cos.ap-chengdu.myqcloud.com"
       :auto-upload="true"
       :http-request="uploadImage"
       :before-upload="beforePicUpload"
       :limit="1">
     <el-button size="small" type="primary" icon="el-icon-picture-outline">上传封面</el-button>
     &nbsp;&nbsp;<span slot="tip" class="el-upload__tip">支持500kb,格式jpg</span>
   </el-upload>
</el-form-item>

接下来写before-upload:上传文件之前的钩子:

async beforePicUpload() {
  await this.getSign();
},


async getSign() {
  //让这个请求变成同步请求
  await this.$http.get("/common/oss/sign").then(response => {
    //接收预签名url链接
    this.uploadUrl = response.data.data; //或者 response.data
  });
},

比较复杂的就是http-request:自定义上传的实现了,我其实也不怎么会前端,所以有些参数也看不懂:

//自定义上传
uploadImage: function (file) {
  // 这里的`file`参数是要上传的文件对象
  // 在这里根据需要添加一些逻辑,如显示进度条
  
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    //element-ui默认使用post提交,但是我们生成的url需要使用 put 提交
    //需要指定 put 直传,以及this.uploadUrl(后端返回的url)
    xhr.open('PUT', this.uploadUrl, true);
    //设置上传文件的类型
    xhr.setRequestHeader('Content-Type', file.file.type); // 或者 file.type
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          resolve(xhr.response);
          //进入到这里就表明上传成功了
          //我这里对后端返回的url进行截取方便存入数据库,因为前端还需要展示图片
          let indexOf = this.uploadUrl.indexOf("?");
          this.addForm.pic = this.uploadUrl.slice(0,indexOf);
        } else {
          reject(xhr.statusText);
        }
      }
    };
    xhr.onerror = () => {
      reject(xhr.statusText);
    };
    //发送
    xhr.send(file.file); //或者 file
  });
},

上传成功后就能在腾讯云cos服务器上看得到了。

总结

其实看看就行了,我也只是完成前端直传cos的功能,也仅仅只是完成功能而已,只是作为学习使用,分享一下。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值