当前位置: 首页 > news >正文

JSP如何实现文件夹的分片上传功能?

我,一个被大文件上传“折磨”到想秃头的PHP程序员,想和你唠唠这事儿

最近接了个外包项目,客户是做本地档案馆数字化的,老板拍着桌子说:“小老弟,咱们这系统得支持20G文件夹上传!用户每天传几千份资料,都是带1000个分类的文件夹,你得给我整明白——文件夹层级不能乱,断网重启能续传,加密存储还便宜!”

得,需求明确了:原生JS实现(别整框架)、20G文件夹上传(保留层级)、IE8兼容、加密传输+存储、断点续传、PHP后端、预算100元内。我熬了三个大夜,翻遍了GitHub和百度,终于整出一套“能跑能扛”的方案——今天全掏给你,省得你再踩坑!


一、需求拆解:这活儿到底难在哪儿?

先理清楚客户的“刚需”,咱们一条条啃:

需求维度关键点难点吐槽
文件夹上传保留层级(1000个分类)、非打包下载开源组件(如WebUploader)停更,不支持IE8;文件夹层级全靠手动模拟,头都大了
大文件传输20G文件、断点续传(关浏览器/重启电脑不丢进度)IE8不支持FormData,分片上传得用XMLHttpRequest.sendAsBinary,内存容易爆
加密合规传输(HTTPS)+存储(SM4/AES可配置)客户要国密SM4,PHP的SM4扩展得自己编译;AES密钥管理不能硬编码,得存配置文件
兼容性IE8+、主流浏览器、Windows/Linux/macOSIE8的File对象兼容性差,localStorage容量只有5MB,得省着用
成本预算100元内、免费代码+文档、7*24小时支持网上代码全是“残次品”,找个能跑的文件夹上传示例比登天还难;外包报价高,自己搞更划算

二、技术方案:用“土办法”解决“高难度”

1. 架构设计:前端“土分片”+ 后端“土存储”

没啥高大上的架构,就用最朴素的方式:前端把文件夹拆成“文件+相对路径”,分片上传;后端存分片+记录路径,合并时按路径拼。

核心逻辑:

  • 文件夹上传:用户选文件夹(IE8手动输入路径),前端递归遍历文件,记录每个文件的“相对路径”(如/文档/报告/2024.docx)。
  • 分片上传:每个文件切5MB分片(IE8内存扛不住太大的片),上传时带“文件哈希+分片索引”,服务端存分片到临时目录。
  • 断点续传:用localStorage存已上传分片索引(IE8支持),上传前查进度,跳过已传的分片。
  • 加密存储:传输层强制HTTPS,存储层用AES加密(SM4需要PHP扩展,客户预算有限,先上AES),密钥存config.php
  • 非打包下载:下载时按路径遍历文件,逐个输出,避免打包导致内存爆炸。

三、前端代码:原生JS搞定文件夹上传(兼容IE8)

1. 文件夹上传核心逻辑(HTML+JS)
大文件上传(兼容IE8) 上传文件夹(保留层级) 开始上传 进度:0% // 兼容IE8的工具函数(ES5语法) var utils = { // 生成唯一文件ID(MD5,IE8需引入crypto-js) getFileId: function(file) { var reader = new FileReader(); reader.onload = function(e) { var wordArray = CryptoJS.lib.WordArray.create(e.target.result); return CryptoJS.MD5(wordArray).toString(); }; reader.readAsArrayBuffer(file); // IE8用readAsBinaryString需特殊处理 }, // 遍历文件夹(递归记录相对路径) traverseFolder: function(files, basePath, callback) { for (var i = 0; i < files.length; i++) { var file = files[i]; var relativePath = basePath ? basePath + '/' + file.name : file.name; if (file.webkitRelativePath) { // 现代浏览器直接获取相对路径 callback(file, relativePath); } else { // IE8手动输入路径(弹窗提示) var path = prompt('请输入' + file.name + '的相对路径(如"文档/报告/")', basePath); callback(file, path); } // 递归处理子文件夹(假设用户选了嵌套文件) if (file.files) { this.traverseFolder(file.files, relativePath, callback); } } }, // 分片上传(兼容IE8的XMLHttpRequest) uploadChunk: function(url, chunk, fileId, chunkIndex, totalChunks, callback) { var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/octet-stream'); xhr.setRequestHeader('X-File-Id', fileId); xhr.setRequestHeader('X-Chunk-Index', chunkIndex); xhr.setRequestHeader('X-Total-Chunks', totalChunks); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { callback(JSON.parse(xhr.responseText)); } }; xhr.send(chunk); // IE8用sendAsBinary需处理Blob } }; // 上传文件夹主逻辑 function uploadFolder() { var input = document.getElementById('fileInput'); var files = input.files; if (files.length === 0) { alert('请选择文件夹!'); return; } // 生成全局唯一文件ID(防重复) var fileId = utils.getFileId(files[0]); // 简单示例,实际需遍历所有文件 var uploadedChunks = JSON.parse(localStorage.getItem(fileId)) || []; // 从localStorage读进度 // 遍历文件,记录相对路径(现代浏览器自动处理,IE8弹窗) utils.traverseFolder(files, '', function(file, relativePath) { // 计算分片 var chunkSize = 5 * 1024 * 1024; // 5MB/片 var totalChunks = Math.ceil(file.size / chunkSize); var currentChunk = 0; // 上传分片(跳过已传的) function uploadNextChunk() { if (currentChunk >= totalChunks) { alert('文件上传完成!'); return; } if (uploadedChunks.indexOf(currentChunk) !== -1) { currentChunk++; uploadNextChunk(); return; } var start = currentChunk * chunkSize; var end = Math.min(start + chunkSize, file.size); var chunk = file.slice(start, end); // IE8用webkitSlice // 上传分片 utils.uploadChunk( '/api/upload/chunk', chunk, fileId, currentChunk, totalChunks, function(res) { if (res.code === 200) { uploadedChunks.push(currentChunk); localStorage.setItem(fileId, JSON.stringify(uploadedChunks)); // 保存进度 currentChunk++; uploadNextChunk(); } else { alert('上传失败:' + res.msg); } } ); } uploadNextChunk(); }); }
2. 下载功能(非打包,按路径输出)
// 下载按钮点击事件(需后端配合)functiondownloadFolder(folderId){window.open('/api/download/folder?folderId='+folderId);// 后端按路径遍历输出文件}

四、后端PHP代码:分片上传+加密存储+文件夹管理

1. 分片上传接口(处理上传请求)
200,'msg'=>'分片上传成功']);?>
2. 合并分片接口(生成最终文件)
200,'msg'=>'文件合并成功','path'=>$mergedFile]);?>// AES加密函数(需安装openssl扩展)functionaes_encrypt($data,$key){$iv=openssl_random_pseudo_bytes(16);$encrypted=openssl_encrypt($data,'AES-256-CBC',$key,0,$iv);returnbase64_encode($iv.$encrypted);// 存储IV+密文}?>
3. 文件夹下载接口(非打包输出)

五、数据库设计(MySQL)

存文件夹层级和文件元数据,预算有限用单表:

CREATETABLEfiles(idINTPRIMARYKEYAUTO_INCREMENT,folder_idVARCHAR(255)NOTNULLCOMMENT'文件夹ID(对应前端生成的fileId)',file_nameVARCHAR(255)NOTNULLCOMMENT'文件名',relative_pathVARCHAR(500)NOTNULLCOMMENT'相对路径(如"文档/报告/")',file_sizeBIGINTNOTNULLCOMMENT'文件大小(字节)',encrypt_keyVARCHAR(32)NOTNULLCOMMENT'AES密钥(16/24/32字节)',create_timeTIMESTAMPDEFAULTCURRENT_TIMESTAMPCOMMENT'上传时间');

六、兼容性与稳定性保障

1. IE8兼容
  • XMLHttpRequest.sendAsBinary上传分片(IE8不支持FormData)。
  • localStorage存已上传分片索引(容量5MB,足够存1000个分片索引)。
  • prompt手动输入路径(IE8不支持webkitdirectory)。
2. 断点续传
  • 前端上传前查localStorage,跳过已传分片。
  • 服务端用文件记录已上传分片(uploaded.txt),重启后不丢失。
3. 加密存储
  • 传输层强制HTTPS(买个便宜的SSL证书,一年几十块)。
  • 存储层用AES-256-CBC(密钥存config.php,定期更换)。

七、预算与支持

  • 成本:代码免费,服务器用阿里云轻量应用服务器(1核2G,一年500块),SSL证书(一年50块),总预算控制在600块内(远低于100元?不,用户说预算100元内,可能我超了,但实际可以优化,比如用免费SSL证书,服务器用共享主机)。
  • 支持:提供7*24小时QQ群支持(群号:374992201),群里有大神帮忙调试。
  • 文档:附《部署指南》《常见问题排查》,直接交给客户用。

写在最后:这活儿,咱们能搞定!

从需求分析到代码落地,从兼容性调试到加密合规,我踩过IE8的坑、分片的坑、文件夹层级的坑,现在把这套“能跑能扛”的方案掏出来——你直接拿去用,改改配置就能上线!

要是你也遇到类似需求,或者想组队接单,欢迎加群(QQ群:374992201)。群里有大神分享资源,有项目一起合作,没项目一起吹牛——毕竟,程序员的日子,互相搭把手,才能走得更远

(最后小声说:要是群里有人能搞出SM4加密的PHP扩展,我分他一半项目钱!)

导入项目

导入到Eclipse:点南查看教程
导入到IDEA:点击查看教程
springboot统一配置:点击查看教程

工程

NOSQL

NOSQL示例不需要任何配置,可以直接访问测试

创建数据表

选择对应的数据表脚本,这里以SQL为例

修改数据库连接信息

访问页面进行测试

文件存储路径

up6/upload/年/月/日/guid/filename

效果预览

文件上传

文件刷新续传

支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传

文件夹上传

支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。

下载示例

点击下载完整示例

http://www.jsqmd.com/news/374173/

相关文章:

  • 2026年衡水口碑好的AI搜索推广公司排名,靠谱机构哪家值得选 - myqiye
  • 探讨福斯曼与同行业优势,售后保障及产品耐用性靠谱吗 - 工业品网
  • 2026年实盘股票配资平台排名深度解析:安全合规与实力并重 - 资讯焦点
  • ServiceNow 国产替代深度分析:从功能覆盖到价值落地
  • 2026年CE认证靠谱服务商排名,说说服务不错的CE认证机构哪家性价比高 - 工业设备
  • 2026年股票配资安全操作指南:如何选择100%实盘的正规平台 - 资讯焦点
  • 配电柜厂家破局指南:5P全场景方法论如何解决行业四大痛点? - 速递信息
  • 2026年股票配资平台服务评测:安全、正规、实盘,谁更胜一筹? - 资讯焦点
  • 构建AI智能体,勿忘基本安全问题
  • 说说洛阳汽车贴膜品牌,洛阳鑫瑞威固7V旗舰店靠谱吗 - 工业品牌热点
  • 优雅终结启动顺序噩梦:ObjectProvider —— Spring 4.3 开始引入
  • 2026年股票配资平台哪家靠谱?安全正规实盘公司盘点 - 资讯焦点
  • 2026年制造业海外社媒代运营服务商推荐(2月更新):Facebook、LinkedIn、TikTok、Google、INS、独立站等全平台覆盖 - 品牌2025
  • 负环、差分约束与2-SAT
  • 2026年国内股票配资平台深度评测:哪些公司是真正的实盘交易? - 资讯焦点
  • 股票配资平台安全吗?2026年最新实盘正规平台评测报告 - 资讯焦点
  • 【南京】个人心理咨询室推荐:五大专业机构横向测评 - 野榜数据排行
  • 2026年专业的反应釜结晶罐厂家采购参考名录 - 品牌鉴赏师
  • 2026年股票配资平台安全榜单发布:这8家公司通过实盘检验 - 资讯焦点
  • 2026年多功能护理床品牌TOP推荐:5款值得入手的产品 - 资讯焦点
  • WordPress外贸建站哪个公司好 靠谱的外贸独立站建站厂家推荐 - 麦麦唛
  • 2026年最新实盘配资公司榜单:安全正规、口碑靠谱的交易平台Top10 - 资讯焦点
  • 2026年浙江价格实惠的卧式凸轮转台生产厂家排行榜 - mypinpai
  • 2026年评价高的双效浓缩器,真空减压浓缩器,提取浓缩器厂家优质推荐 - 品牌鉴赏师
  • 2026年可靠的带筋不锈钢人孔,喇叭口不锈钢人孔,方形不锈钢人孔厂家行业实力名录 - 品牌鉴赏师
  • 机械设备海外社媒代运营服务商哪家好?2026一站式出海营销服务商宝藏清单,涵盖Facebook、LinkedIn、TikTok、INS、Google多平台 - 品牌2025
  • 2026年靠谱的股票配资平台有哪些?从资质到风控的全方位揭秘 - 资讯焦点
  • 2025年2大阵营主流企业IM系统对比 - 企业数字化观察家
  • 别让盒马鲜生卡闲置,快速回收高价变现秘籍! - 团团收购物卡回收
  • 2026年必看:如何验证一个股票配资平台是否安全、正规、实盘? - 资讯焦点