芯片制造中PHP如何处理视频大附件的分块上传分享?
咱是辽宁的一个“老码农”最近接了个外包项目客户要做大文件上传功能要求还挺“硬核”——原生JS实现、20G文件传输、文件夹保留层级、加密传输存储、断点续传兼容IE9… 预算还卡在100块以内老板说“小项目不搞虚的”。咱一边啃着锅包肉一边想“这活得整明白不然别说接单了客户都得跑”先唠唠客户的“离谱”需求但必须满足大文件文件夹20G文件1000子文件的文件夹每天批量上传得稳得住。断点续传用户关浏览器、重启电脑都不丢进度咱就想这用户怕不是经常断电。加密传输用SM4/AES存储也加密客户说“数据安全比命重要”。兼容IE9部分用户还在Win7IE9咱叹气“这浏览器比我还老…”。非打包下载几万文件打包服务器直接崩客户“之前打包方案被骂惨了”。咱的“土味”解决方案能跑就行没找开源组件要么停更要么不支持咱自己整了个“原生JSSpringBoot”的组合拳——前端用原生File API分片后端用SpringBoot管分片数据库记进度加密用AESSM4类似换库就行。一、前端Vue3 原生JS兼容IE9代码尽量简单老码农看得懂新手能跑通import CryptoJS from crypto-js; // 加密用npm install crypto-js export default { data() { return { uploading: false, progress: 0, chunkSize: 5 * 1024 * 1024, // 5MB分片20G分4000片 file: null, folderStructure: {}, // 记录文件夹层级 { path/to/file.txt: { size: 1024, chunks: [] } } uploadId: null, // 全局唯一ID断点续传标识 uploadedChunks: new Set() // 已上传分片 }; }, methods: { async handleFileSelect(e) { const files e.target.files; if (!files.length) return; this.file files[0]; // 生成全局唯一uploadId时间戳随机数 this.uploadId upload_${Date.now()}_${Math.random().toString(36).slice(2, 8)}; // 解析文件夹结构IE9用FileReader模拟 this.parseFolderStructure(files); // 检查后端已上传分片 await this.checkUploadedChunks(); // 开始上传 this.uploadAllChunks(); }, // 解析文件夹结构兼容IE9 parseFolderStructure(files) { Array.from(files).forEach(file { // IE9不支持webkitRelativePath用FileReader读路径土办法 const reader new FileReader(); reader.onload (e) { // 实际路径需用File API获取IE9用其他方法这里简化 const path file.webkitRelativePath || unknown/${file.name}; this.folderStructure[path] { size: file.size, chunks: [], uploaded: false }; }; reader.readAsDataURL(file); }); }, // 检查已上传分片后端接口 async checkUploadedChunks() { const res await this.$http.get(/api/upload/check?uploadId${this.uploadId}); this.uploadedChunks new Set(res.data.uploadedChunks); this.progress (this.uploadedChunks.size / this.totalChunks) * 100; }, // 上传所有分片控制并发防崩溃 async uploadAllChunks() { this.uploading true; const totalChunks Math.ceil(this.file.size / this.chunkSize); for (let i 0; i totalChunks; i) { if (this.uploadedChunks.has(i)) { this.progress (i / totalChunks) * 100; continue; } const start i * this.chunkSize; const end Math.min(start this.chunkSize, this.file.size); const chunk this.file.slice(start, end); // 加密分片AES密钥从后端获取 const encryptedChunk await this.encryptChunk(chunk); // 构造FormDataIE9用XHRiframe const formData new FormData(); formData.append(file, encryptedChunk, ${this.uploadId}_${i}); formData.append(chunkIndex, i); formData.append(totalChunks, totalChunks); formData.append(uploadId, this.uploadId); formData.append(filePath, this.filePath); try { // 发送请求IE9用xhr const res await this.$http.post(/api/upload/chunk, formData); this.uploadedChunks.add(i); this.progress (i / totalChunks) * 100; } catch (err) { console.error(上传失败:, err); break; } } // 合并分片 if (this.uploadedChunks.size totalChunks) { await this.mergeChunks(); } this.uploading false; }, // 加密分片AES示例 async encryptChunk(chunk) { const key 客户提供的AES密钥16位; // 从后端获取更安全 const iv CryptoJS.lib.WordArray.random(16); // 随机IV const encrypted CryptoJS.AES.encrypt( CryptoJS.lib.WordArray.create(chunk), CryptoJS.enc.Utf8.parse(key), { iv: iv } ); return new Blob([iv.toString(), encrypted.toString()], { type: application/octet-stream }); }, // 合并分片触发后端合并 async mergeChunks() { const res await this.$http.post(/api/upload/merge, { uploadId: this.uploadId, fileName: this.file.name, totalChunks: this.totalChunks, filePath: this.filePath }); if (res.code 200) { alert(上传成功); } } } };二、后端SpringBoot分片管理加密存储代码简洁兼容老版本数据库记进度// FileUploadController.java处理上传接口RestControllerRequestMapping(/api/upload)publicclassFileUploadController{Value(${upload.temp.path})privateStringtempPath;// 临时分片路径如/data/tempValue(${upload.final.path})privateStringfinalPath;// 最终存储路径如/data/filesAutowiredprivateFileUploadMapperuploadMapper;// MyBatis Mapper// 检查已上传分片GetMapping(/check)publicMapcheckChunks(RequestParamStringuploadId){ListuploadedChunksuploadMapper.selectUploadedChunks(uploadId);returnMap.of(uploadedChunks,uploadedChunks);}// 接收分片PostMapping(/chunk)publicMapuploadChunk(RequestParam(file)MultipartFilefile,RequestParamintchunkIndex,RequestParaminttotalChunks,RequestParamStringuploadId,RequestParamStringfilePath){// 创建临时目录StringtempDirtempPath/uploadId;FiledirnewFile(tempDir);if(!dir.exists())dir.mkdirs();// 保存分片后端不解密仅存储StringchunkPathtempDir/chunkIndex;try{file.transferTo(newFile(chunkPath));}catch(IOExceptione){returnMap.of(code,500,msg,分片保存失败);}// 记录进度到数据库uploadMapper.insertUploadProgress(uploadId,chunkIndex,filePath);returnMap.of(code,200);}// 合并分片解密后合并PostMapping(/merge)publicMapmergeChunks(RequestParamStringuploadId,RequestParamStringfileName,RequestParaminttotalChunks,RequestParamStringfilePath){StringtempDirtempPath/uploadId;StringfinalFilePathfinalPath/filePath/fileName;try(RandomAccessFilerafnewRandomAccessFile(finalFilePath,rw)){for(inti0;itotalChunks;i){StringchunkPathtempDir/i;byte[]chunkDataFiles.readAllBytes(Paths.get(chunkPath));byte[]decryptedDataaesDecrypt(chunkData);// AES解密raf.write(decryptedData);Files.delete(Paths.get(chunkPath));// 删除临时分片}}catch(IOExceptione){returnMap.of(code,500,msg,合并失败);}// 清理数据库记录uploadMapper.deleteUploadProgress(uploadId);returnMap.of(code,200,msg,合并成功);}// AES解密密钥从配置中心获取privatebyte[]aesDecrypt(byte[]data){Stringkey客户提供的AES密钥16位;// 实际从配置/数据库获取// 解密逻辑AES/CBC/PKCS5PaddingreturndecryptedData;}}// FileUploadMapper.javaMyBatis操作数据库publicinterfaceFileUploadMapper{Select(SELECT chunk_index FROM file_upload_progress WHERE upload_id #{uploadId})ListselectUploadedChunks(Param(uploadId)StringuploadId);Insert(INSERT INTO file_upload_progress (upload_id, chunk_index, file_path) VALUES (#{uploadId}, #{chunkIndex}, #{filePath}) ON DUPLICATE KEY UPDATE chunk_index #{chunkIndex})voidinsertUploadProgress(Param(uploadId)StringuploadId,Param(chunkIndex)intchunkIndex,Param(filePath)StringfilePath);Delete(DELETE FROM file_upload_progress WHERE upload_id #{uploadId})voiddeleteUploadProgress(Param(uploadId)StringuploadId);}三、数据库表结构MySQLCREATETABLEfile_upload_progress(idINTPRIMARYKEYAUTO_INCREMENT,upload_idVARCHAR(64)NOTNULLCOMMENT全局上传ID,chunk_indexINTNOTNULLCOMMENT分片序号,file_pathVARCHAR(255)NOTNULLCOMMENT文件/文件夹路径,UNIQUEKEYuk_upload_chunk(upload_id,chunk_index)-- 防重复分片);咱的“保姆级”支持预算有限但服务到位代码完整提供前端Vue3组件含IE9兼容补丁、后端SpringBoot代码含MyBatis配置、数据库脚本解压就能跑。部署简单写了一键打包脚本npm run buildmvn packageTomcat扔WAR包MySQL导入SQL就行。加密支持AES密钥可配置客户自己保管SM4换库就能用附BouncyCastle集成文档。兼容兜底IE9用iframe模拟上传代码里标了注释现代浏览器用原生Fetch主流浏览器全支持。最后唠唠接单群资源分享咱建了个QQ群374992201专门拉“外包码农”和“找项目的老板”——群里福利拉满新人加群送1~99元红包手慢无推荐项目拿20%提成2万项目提4千比外卖自由香多了技术交流大文件上传、加密、兼容问题随便问老码农在线答疑内推工作沈阳IT圈岗位大厂外包都有。咱这项目要是成了答辩老师看了都得夸“这程序员有点东西” 赶紧加群一起搞钱一起秃一起当“外包大佬”PS群里还有人分享“如何用AI写文档”的玄学技巧亲测能过甲方审核安装环境PHP:7.2.14调整块大小NOSQLNOSQL不需要任何配置可以直接访问测试SQL创建数据库您可以直接复制脚本进行创建配置数据库连接安装依赖访问页面进行测试数据表中的数据效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。免费下载示例点击下载完整示例

相关新闻

教育网站如何利用UEDITOR实现微信公众号内容迁移?

教育网站如何利用UEDITOR实现微信公众号内容迁移?

程序员的外包奇遇记:Word一键粘贴大作战 大家好,我就是那个在安徽码PHP的"秃"出程序员!最近接了个CMS企业官网的活儿,客户爸爸突然甩来一个需求… 需求来了! “小张啊,我们这个新闻发布系统啊…

2026/7/3 4:27:46 阅读更多 →
Java链表实现教程:节点定义与增删操作详解

Java链表实现教程:节点定义与增删操作详解

链表是数据结构中的基础,在Java中实现链表能帮助我们理解对象引用和动态内存管理的核心机制。与数组不同,链表通过节点间的引用连接数据,提供了更灵活的数据组织方式。掌握链表的Java实现,是深入理解集合框架底层和解决特定算法问…

2026/7/2 20:21:17 阅读更多 →
免费STL文件下载网站推荐,3D打印避坑指南

免费STL文件下载网站推荐,3D打印避坑指南

在寻找3D打印模型时,获取高质量、可用的STL文件是关键的第一步。作为多年的3D打印爱好者,我深知选择一个靠谱的STL文件下载网站,直接关系到打印项目的成败。本文将结合我的实际使用经验,为你剖析几个主流平台的核心差异和避坑要点…

2026/7/3 17:22:13 阅读更多 →

最新新闻

多智能体系统安全控制与责任分配技术解析

多智能体系统安全控制与责任分配技术解析

1. 多智能体系统安全责任分配的核心挑战 在机器人集群、无人机编队等典型多智能体系统中,安全责任分配面临三个维度的核心挑战: 1.1 安全性与自主性的矛盾 传统集中式控制虽然能保证全局安全,但要求所有智能体公开完整状态信息&#xff0c…

2026/7/4 17:41:06 阅读更多 →
深度解析开源抖音下载器:3大技术优势与实战部署指南

深度解析开源抖音下载器:3大技术优势与实战部署指南

深度解析开源抖音下载器:3大技术优势与实战部署指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support…

2026/7/4 17:41:06 阅读更多 →
操作系统级缓存:超越Redis的系统性能优化底层原理与实践

操作系统级缓存:超越Redis的系统性能优化底层原理与实践

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 大家好,我是专注于技术实战分享的博主。在追求极致性能的路上,我们常常将目光投向 Redis 这类明星缓存中间件…

2026/7/4 17:39:05 阅读更多 →
揭秘evbunpack:高效破解Enigma Virtual Box打包文件的专业工具

揭秘evbunpack:高效破解Enigma Virtual Box打包文件的专业工具

揭秘evbunpack:高效破解Enigma Virtual Box打包文件的专业工具 【免费下载链接】evbunpack Enigma Virtual Box Unpacker / 解包、脱壳工具 项目地址: https://gitcode.com/gh_mirrors/ev/evbunpack 当你在逆向工程或软件分析工作中遇到Enigma Virtual Box打…

2026/7/4 17:37:04 阅读更多 →
跨平台开发实战:从操作系统差异看远程控制软件适配挑战

跨平台开发实战:从操作系统差异看远程控制软件适配挑战

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Claude 随心用,限时 5 折。 👉 点击领海量免费额度 你是不是也经常遇到这样的困惑:手头一台Windows笔记本办公,家里一台Mac Mini当服务器,还有一台L…

2026/7/4 17:35:03 阅读更多 →
基于YOLOv8的字符识别系统开发与实践

基于YOLOv8的字符识别系统开发与实践

1. 项目概述这个基于YOLOv8的字母数字识别检测系统是我最近完成的一个计算机视觉项目。它能够实时检测并识别图像和视频中的36类字符(数字0-9和字母A-Z),在复杂场景下表现出色。相比传统OCR技术,这个系统最大的优势在于能够处理任…

2026/7/4 17:33:03 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻