Spring Boot + Vue2 實現騰訊云 COS 文件上傳:從零搭建分片上傳系統

目錄

一、項目目標

二、騰訊云 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作為反向代理…