目录

一、项目目标

二、腾讯云 COS 基本配置

1. 创建存储桶

2. 获取 API 密钥

3. 设置跨域规则(CORS)

三、后端(Spring Boot)实现

1. 依赖配置

2. 配置腾讯云 COS(application.yml)

3. 初始化 COS 客户端

4. 文件上传接口

(1)普通上传

(2)分片上传接口

① 初始化分片上传

② 上传分片

③ 合并分片

四、前端(Vue2)实现

1. 安装依赖

2. 分片上传逻辑

五、注意事项与优化

1. 分片大小限制

2. 并发上传优化

3. 断点续传支持

4. 安全性增强

六、总结

一、项目目标

实现基于腾讯云 COS 的 大文件分片上传普通文件上传 功能,前后端分离架构,采用 Vue2 + Spring Boot + YML 配置方式,并覆盖以下注意事项:

  • 分片上传大小限制
  • 并发上传优化
  • 断点续传支持
  • 安全性增强(避免暴露密钥)
  • 跨域规则配置(CORS)

二、腾讯云 COS 基本配置

1. 创建存储桶

登录腾讯云控制台 → 对象存储 COS → 创建存储桶:

  • 存储桶名称:your-bucket-name-1250000000
  • 地域:ap-beijing(根据需求选择)
  • 权限设置:私有读写

2. 获取 API 密钥

前往 API 密钥管理 页面,创建或使用已有 SecretId/SecretKey。

安全建议:前端禁止直接使用 SecretId/SecretKey,应通过后端代理或使用 STS 临时密钥。

3. 设置跨域规则(CORS)

前往 权限管理 → 跨域规则,添加以下规则:

{"allowedOrigin": ["*"],"allowedMethod": ["GET", "POST", "PUT", "HEAD"],"allowedHeader": ["*"],"exposeHeader": [],"maxAgeSeconds": 3000
}

三、后端(Spring Boot)实现

1. 依赖配置

<dependencies><!-- Spring Boot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 腾讯云 COS SDK --><dependency><groupId>com.qcloud</groupId><artifactId>cos_api</artifactId><version>5.2.4</version></dependency><!-- 工具类 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>
</dependencies>

2. 配置腾讯云 COS(application.yml

tencent:cos:secret-id: YOUR_SECRET_IDsecret-key: YOUR_SECRET_KEYregion: ap-beijingbucket-name: your-bucket-name-1250000000

3. 初始化 COS 客户端

import com.qcloud.cos.COSClient;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.region.Region;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class CosConfig {@Value("${tencent.cos.secret-id}")private String secretId;@Value("${tencent.cos.secret-key}")private String secretKey;@Value("${tencent.cos.region}")private String region;@Beanpublic COSClient cosClient() {COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);Region cosRegion = new Region(region);return new COSClient(cred, cosRegion);}
}

4. 文件上传接口

(1)普通上传
import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;
import java.util.UUID;@RestController
@RequestMapping("/api/upload")
public class UploadController {@Autowiredprivate COSClient cosClient;@Value("${tencent.cos.bucket-name}")private String bucketName;@PostMapping("/simple")public String simpleUpload(@RequestParam("file") MultipartFile file) {try {String remoteFileName = "uploads/" + UUID.randomUUID().toString() + "-" + file.getOriginalFilename();InputStream inputStream = file.getInputStream();PutObjectRequest request = new PutObjectRequest(bucketName, remoteFileName, inputStream, null);cosClient.putObject(request);return "https://" + bucketName + ".cos." + cosClient.getClientConfig().getRegion().getName() + ".myqcloud.com/" + remoteFileName;} catch (Exception e) {return "上传失败: " + e.getMessage();}}
}
(2)分片上传接口
① 初始化分片上传
@PostMapping("/init")
public String initMultipartUpload(@RequestParam String fileName) {try {InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, fileName);return cosClient.initiateMultipartUpload(request).getUploadId();} catch (Exception e) {return "初始化失败: " + e.getMessage();}
}
② 上传分片
@PostMapping("/part")
public String uploadPart(@RequestParam("file") MultipartFile file,@RequestParam("uploadId") String uploadId,@RequestParam("partNumber") int partNumber,@RequestParam("fileName") String fileName) {try {UploadPartRequest request = new UploadPartRequest().withBucketName(bucketName).withKey(fileName).withUploadId(uploadId).withPartNumber(partNumber).withInputStream(file.getInputStream()).withPartSize(file.getSize());return cosClient.uploadPart(request).getETag(); // 返回 ETag} catch (Exception e) {return "分片上传失败: " + e.getMessage();}
}
③ 合并分片
@PostMapping("/complete")
public String completeMultipartUpload(@RequestParam("fileName") String fileName,@RequestParam("uploadId") String uploadId,@RequestParam("partETags") List<String> partETags) {try {List<PartETag> partETagList = partETags.stream().map(etag -> new PartETag(partETags.indexOf(etag) + 1, etag)).toList();CompleteMultipartUploadRequest request = new CompleteMultipartUploadRequest(bucketName, fileName, uploadId, partETagList);cosClient.completeMultipartUpload(request);return "https://" + bucketName + ".cos." + cosClient.getClientConfig().getRegion().getName() + ".myqcloud.com/" + fileName;} catch (Exception e) {return "合并失败: " + e.getMessage();}
}

四、前端(Vue2)实现

1. 安装依赖

npm install axios

2. 分片上传逻辑

<template><div><input type="file" @change="handleFileChange" /><button @click="uploadFile">上传</button><div>上传进度: {{ progress }}%</div></div>
</template><script>
import axios from 'axios';export default {data() {return {file: null,uploadId: '',chunkSize: 5 * 1024 * 1024, // 5MBprogress: 0,uploadedChunks: [], // 已上传的分片索引};},methods: {handleFileChange(event) {this.file = event.target.files[0];this.uploadedChunks = [];this.progress = 0;},async uploadFile() {if (!this.file) {alert("请选择文件");return;}// 1. 初始化分片上传const initRes = await axios.post('/api/upload/init', {fileName: this.file.name,});this.uploadId = initRes.data;// 2. 并发上传分片const totalChunks = Math.ceil(this.file.size / this.chunkSize);const promises = [];for (let i = 0; i < totalChunks; i++) {const start = i * this.chunkSize;const end = Math.min(start + this.chunkSize, this.file.size);if (this.uploadedChunks.includes(i)) continue; // 跳过已上传分片const chunk = this.file.slice(start, end);const formData = new FormData();formData.append('file', chunk);formData.append('uploadId', this.uploadId);formData.append('partNumber', i + 1);formData.append('fileName', this.file.name);const promise = axios.post('/api/upload/part', formData, {onUploadProgress: (progressEvent) => {const percent = Math.round(((this.uploadedChunks.length * 100) / totalChunks) +((progressEvent.loaded / progressEvent.total) * 100 / totalChunks));this.progress = percent;},});promises.push(promise.then(() => {this.uploadedChunks.push(i); // 标记为已上传}));}// 并发上传await Promise.all(promises);// 3. 合并分片const completeRes = await axios.post('/api/upload/complete', {fileName: this.file.name,uploadId: this.uploadId,partETags: [], // 后端应返回每个分片的 ETag});alert("上传成功: " + completeRes.data);},},
};
</script>

五、注意事项与优化

1. 分片大小限制

  • 腾讯云要求 单个分片最小 1MB,最大 5GB
  • 推荐设置 chunkSize = 5 * 1024 * 1024(5MB)。

2. 并发上传优化

  • 使用 Promise.all 实现并发上传,提升上传效率。
  • 可设置最大并发数,避免过多请求导致服务器压力过大。

3. 断点续传支持

  • 通过 this.uploadedChunks 记录已上传分片索引。
  • 重启上传时跳过已上传部分,实现断点续传。

4. 安全性增强

  • 禁止前端暴露 SecretId/SecretKey
  • 建议使用 STS 临时密钥 或 后端代理上传
    • 后端可封装上传逻辑,前端仅调用后端接口上传文件。
    • 使用腾讯云 STS 获取临时密钥,设置访问权限和有效期。

六、总结

本教程完整实现了基于 Spring Boot + Vue2 的腾讯云 COS 文件上传功能,支持:

  • 普通上传
  • 大文件分片上传(支持并发、断点续传)
  • 安全性增强(密钥不暴露)
  • 跨域规则配置(CORS)

可根据实际业务需求进一步扩展,如添加上传进度持久化、上传失败重试机制等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89004.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89004.shtml
英文地址,请注明出处:http://en.pswp.cn/web/89004.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Java 获取 PDF 页面信息(页数、尺寸、旋转角度、方向、标签与边框)

目录 引言 一、安装和引入PDF处理库 二、获取 PDF 页数 三、获取页面尺寸&#xff08;宽高&#xff09; 四、获取页面旋转角度 五、判断页面方向&#xff08;横向 / 纵向&#xff09; 六、获取页面标签 七、获取页面边框信息 八、总结 引言 了解 PDF 页面属性是我们在…

基于 AI 的大前端安全态势感知与应急响应体系建设

大前端应用&#xff08;Web、APP、小程序&#xff09;作为用户交互的入口&#xff0c;面临日益复杂的安全威胁&#xff1a;从传统的 XSS 攻击、CSRF 伪造&#xff0c;到新型的供应链投毒、AI 驱动的自动化爬虫&#xff0c;再到针对业务逻辑的欺诈攻击&#xff08;如薅羊毛、账号…

Java 与 MySQL 性能优化:MySQL全文检索查询优化实践

文章目录一、引言二、InnoDB引擎下的全文检索功能详解2.1 全文索引的基本概念与原理2.2 全文索引的创建与管理2.3 全文检索的三种查询模式2.4 中文全文检索的挑战与解决方案三、CMS 场景下的全文检索性能瓶颈分析3.1 索引构建与维护开销3.2 查询性能瓶颈3.3 锁机制与并发性能问…

应用软件格式渗透 利用word去渗透(MS10-087)

用到的靶机为&#xff1a;WinXP漏洞原理&#xff1a;一、漏洞触发机制与核心组件 漏洞根源&#xff1a;RTF文件解析逻辑缺陷 触发组件&#xff1a;Microsoft Word的RTF&#xff08;Rich Text Format&#xff09;解析引擎&#xff0c;具体涉及 mso.dll 模块中的 路径规范化函数&…

解密AWS VPC路由表:显式关联与隐式关联,谁决定了网络出口?

大家好&#xff0c;今天我们来聊一个在 AWS 云计算世界里既基础又关键的话题&#xff1a;VPC 路由表。 很多刚接触 AWS 的朋友&#xff0c;在配置网络时可能会遇到这样的困惑&#xff1a;为什么我的 EC2 实例无法访问互联网&#xff1f;为什么某些子网的网络策略和其他子网不一…

LeetCode题解---<203.移除链表元素>

文章目录题目代码及注释关键点题目 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,…

【JavaScript高级】构造函数、原型链与数据处理

目录构造函数和原型构造函数实例成员和静态成员构造函数的问题构造函数原型 prototype对象原型 \_\_proto\_\_constructor 构造函数构造函数、实例、原型对象三者之间的关系原型链JavaScript 的成员查找机制&#xff08;规则&#xff09;原型对象的this指向扩展内置对象继承cal…

项目进度与预算脱节,如何进行同步管理

项目进度与预算脱节会导致资源浪费、成本超支和项目延期。进行同步管理的方法包括&#xff1a;建立统一的项目进度预算管理体系、实施实时监控与反馈机制、采用项目管理工具辅助同步管理。尤其是实施实时监控与反馈机制&#xff0c;通过持续监测进度与预算的匹配情况&#xff0…

TCP半关闭

理解TCP半关闭&#xff1a;像水管一样的网络连接控制 从全关闭到半关闭&#xff1a;为什么需要这种机制&#xff1f; 想象你和朋友正在通电话讨论一个重要项目&#xff1a; 全关闭&#xff1a;就像突然挂断电话&#xff0c;双方都无法再说话半关闭&#xff1a;你说"我说完…

衡石科技技术手册--仪表盘过滤控件详解

过滤控件说明 过滤控件 的定义 过滤控件用于在仪表盘中过滤图表数据&#xff0c;分为仪表盘内过滤控件和全局过滤控件。 过滤控件结构说明 字段类型描述uidSTRING过滤控件唯一识别 idappIdLONG过滤控件所属的应用 iddataAppIdLONG字段来源是数据包时的数据包 iddashboar…

ASP.NET Core中数据绑定原理实现详解

在ASP.NET Core 中&#xff0c;数据绑定是将 HTTP 请求中的数据&#xff08;如表单、查询字符串、请求体等&#xff09;映射到控制器动作方法参数或模型对象的过程。以下将从原理、核心组件、执行流程及关键机制等方面详细解析其实现逻辑。 一、数据绑定的核心原理与组件 1. 数…

牛客:HJ24 合唱队[华为机考][最长递增子集][动态规划]

学习要点 求最长递增字列求最长递减子列 题目链接 合唱队_牛客题霸_牛客网 题目描述 解法&#xff1a;动归求最长递增子列 #include <iostream> #include <vector> using namespace std;int main() {int n;while (cin >> n) {// 输入的数组int tmp;vect…

C语言的相关基础概念和常用基本数据类型

1.相关概念变量与常量的定义常量&#xff1a;在程序运行中其值不能改变的量。变量&#xff1a;在程序运行中其值可以改变的量。存储器的区分 RAMROM中文名易失存储器不易失存储器特点掉电丢失数据&#xff0c;但存取快掉电不丢失数据&#xff0c;但存取幔标识符标识符只能…

Spring boot整合dubbo+zookeeper

Spring boot整合dubbozookeeper 下文将简述springboot整合dubbozookeeper实现apiproviderconsumer模式&#xff0c;Api用于定于interface,provider和consumer依赖Api,provider实现api接口&#xff0c;consumer调用provider。 spring boot版本&#xff1a;3.5.3 jdk版本&#xf…

ImportError: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.32‘ not found

简介&#xff1a;在复现 VLM-R1 项目并尝试将其中的 GRPO 算法应用到自己的任务时&#xff0c;按照官方文档配置好环境后&#xff0c;运行过程中遇到了一个非常离谱的错误&#xff1a; ImportError: /lib/x86_64-linux-gnu/libc.so.6: version GLIBC_2.32 not found 这个问题极…

基于Spring Boot的生活用品电商网站的设计与实现

第1章 摘要随着电商行业的飞速发展&#xff0c;生活用品电商网站作为线上购物的一部分&#xff0c;逐渐成为消费者日常购物的重要渠道。为提升网站的管理效率和用户体验&#xff0c;设计并实现了一款基于Spring Boot的生活用品电商网站。该系统通过合理的架构设计&#xff0c;提…

数据结构 单链表(1)

1.概念和结构概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的。通过指针链接次序实现的要怎么理解呢?这是一张链表的结构图:与顺序表不同的是&#xff0c;链表里的每节“车厢” (仔细观察这…

Python爬虫实战:研究PyMongo库相关技术

1. 引言 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地获取这些数据并进行存储和分析,成为了数据科学领域的重要研究方向。网络爬虫作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 MongoDB 作为一种流行的 NoSQL 数据库,能够灵…

【世纪龙科技】迈腾B8汽车整车检测与诊断仿真实训系统

在汽车技术日新月异的今天&#xff0c;如何培养既懂理论又精实践的高素质汽修人才&#xff0c;成为职业教育领域亟待突破的课题。江苏世纪龙科技凭借深厚的技术积淀与教育洞察&#xff0c;重磅推出《汽车整车检测与诊断仿真实训系统》&#xff0c;以迈腾B8为原型&#xff0c;通…

.net服务器Kestrel配置Nginx作为反向代理

.NET服务器Kestrel配置Nginx作为反向代理 在ASP.NET Core应用程序的部署过程中&#xff0c;Kestrel是一款轻量级的跨平台Web服务器。不过&#xff0c;直接将其暴露在互联网上并非明智之举。为了增强安全性、提升性能以及提高可伸缩性&#xff0c;我们可以借助Nginx作为反向代理…