2026/5/14 11:48:55
网站建设
项目流程
珠海网站制作计划,营销方案范文100例,做标书的网站,wordpress 域名 ip湖南某软件公司前端工程师大文件传输方案#xff08;20G兼容IE8#xff09;
一、需求分析与技术选型 核心需求拆解#xff1a; 文件传输#xff1a; 单文件20G分片上传/下载文件夹递归结构保留#xff08;含空文件夹#xff09;传输中断续传#xff08;MD5校验#xf…湖南某软件公司前端工程师大文件传输方案20G兼容IE8一、需求分析与技术选型核心需求拆解文件传输单文件20G分片上传/下载文件夹递归结构保留含空文件夹传输中断续传MD5校验安全要求传输加密SM4/AES前端可配置存储加密后端透明加密数据库字段级兼容性浏览器IE8、Chrome 45、Firefox 52操作系统Windows 7/10/11、macOS 10.12、LinuxUbuntu 18.04技术选型评估方案优势缺陷适配成本自研方案完全可控兼容性可深度定制开发周期长预估3个月高Plupload 改造成熟分片上传IE8兼容文件夹支持弱无SM4支持中最终选择Resumable.js WebSocket需解决IE8兼容性问题中高关键决策点放弃Flash方案IE8需NPAPI支持现代浏览器已禁用采用File APIBlobFormData组合实现分片使用WebSocket替代XHR实现进度实时推送IE8降级为轮询二、前端实现方案Vue3 TypeScript核心架构设计// src/core/uploader/index.tsinterfaceUploadConfig{chunkSize:number;// 分片大小默认5MBencryptType:SM4|AES;// 加密算法parallel:number;// 并发数默认3retryTimes:number;// 重试次数默认3}classBigFileUploader{privateconfig:UploadConfig;privatefileTree:FileNode[];// 文件夹树结构privatesocket?:WebSocket;constructor(config:Partial{}){this.config{chunkSize:5*1024*1024,encryptType:AES,parallel:3,retryTimes:3,...config};}// 初始化上传兼容IE8publicasyncinitUpload(fileInput:HTMLInputElement){constfilesArray.from(fileInput.files||[]);if(files.length0)return;// 构建文件树保留文件夹结构this.fileTreethis.buildFileTree(files);// 加密策略选择constencryptFnthis.config.encryptTypeSM4?this.sm4Encrypt:this.aesEncrypt;// 分片上传主逻辑for(constfileNodeofthis.fileTree){awaitthis.uploadNode(fileNode,encryptFn);}}// 文件夹递归处理IE8兼容privatebuildFileTree(files:File[]):FileNode[]{// 实现略通过webkitRelativePath或自定义路径解析// 关键点处理IE8的File API缺失问题}}IE8兼容性实现// src/utils/ie8-polyfill.js// 1. Blob切片模拟IE8无Blob.sliceif(!window.Blob.prototype.slice){window.Blob.prototype.slicefunction(start,end){constblobthis;constbbnewwindow.BlobBuilder();// 模拟切片逻辑性能较差// ...returnbb.getBlob();};}// 2. WebSocket降级方案exportfunctioncreateSocket(url:string){if(window.WebSocket){returnnewWebSocket(url);}else{// IE8使用ActiveXObject需用户安装特定控件try{returnnewActiveXObject(Microsoft.XMLHTTP);}catch(e){console.error(WebSocket not supported);returnnull;}}}分片加密上传组件import { defineComponent, ref } from vue; import BigFileUploader from /core/uploader; import { sm4Encrypt, aesEncrypt } from /utils/crypto; export default defineComponent({ setup() { const fileInput refHTMLInputElement | null(null); const progress ref(0); const encryptType refAES | SM4(AES); const uploader new BigFileUploader({ encryptType: encryptType.value }); const handleFileChange () { if (!fileInput.value?.files) return; uploader.initUpload(fileInput.value); }; const updateConfig () { uploader.config.encryptType encryptType.value; }; return { fileInput, progress, encryptType, handleFileChange, updateConfig }; } });三、后端SpringBoot实现关键点分片接收接口// src/main/java/com/example/controller/UploadController.javaRestControllerRequestMapping(/api/upload)publicclassUploadController{PostMapping(/chunk)publicResponseEntityuploadChunk(RequestParam(file)MultipartFilefile,RequestParam(chunkNumber)intchunkNumber,RequestParam(totalChunks)inttotalChunks,RequestParam(fileId)StringfileId,RequestParam(encryptType)StringencryptType){try{// 1. 解密分片根据配置调用SM4/AES解密byte[]decryptedDataCryptoUtil.decrypt(file.getBytes(),encryptType,fileId// 使用fileId作为IV);// 2. 临时存储分片PathtempDirPaths.get(/tmp/uploads/fileId);Files.createDirectories(tempDir);PathchunkPathtempDir.resolve(chunk_chunkNumber);Files.write(chunkPath,decryptedData);// 3. 检查是否所有分片已上传if(chunkNumbertotalChunks){mergeChunks(fileId,totalChunks);}returnResponseEntity.ok(Chunk uploaded successfully);}catch(Exceptione){returnResponseEntity.status(500).body(e.getMessage());}}privatevoidmergeChunks(StringfileId,inttotalChunks)throwsIOException{// 实现分片合并逻辑// ...}}加密存储实现// src/main/java/com/example/util/CryptoUtil.javapublicclassCryptoUtil{privatestaticfinalStringSM4_KEYyour-sm4-key-16bytes;privatestaticfinalStringAES_KEYyour-aes-key-16bytes;publicstaticbyte[]decrypt(byte[]data,Stringalgorithm,Stringiv){try{if(SM4.equalsIgnoreCase(algorithm)){returnsm4Decrypt(data,iv);}else{returnaesDecrypt(data,iv);}}catch(Exceptione){thrownewRuntimeException(Decrypt failed,e);}}privatestaticbyte[]sm4Decrypt(byte[]data,Stringiv)throwsException{// 使用BouncyCastle实现SM4// ...}privatestaticbyte[]aesDecrypt(byte[]data,Stringiv)throwsException{CiphercipherCipher.getInstance(AES/CBC/PKCS5Padding);SecretKeySpeckeySpecnewSecretKeySpec(AES_KEY.getBytes(),AES);IvParameterSpecivSpecnewIvParameterSpec(iv.getBytes());cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec);returncipher.doFinal(data);}}四、关键问题解决方案IE8文件夹上传问题解决方案if (window.navigator.userAgent.indexOf(MSIE 8) -1) { document.querySelector(input[typefile]).removeAttribute(webkitdirectory); alert(IE8不支持文件夹上传请手动选择文件); }大文件内存优化// 使用流式处理避免内存溢出privateasyncuploadLargeFile(file:File,encryptFn:Function){constchunkSizethis.config.chunkSize;consttotalChunksMath.ceil(file.size/chunkSize);for(leti0;itotalChunks;i){conststarti*chunkSize;constendMath.min(startchunkSize,file.size);constchunkfile.slice(start,end);// 使用FileReader流式读取constreadernewFileReader();reader.onloadasync(e){constencryptedencryptFn(e.target?.resultasArrayBuffer);awaitthis.uploadChunk(encrypted,i,totalChunks);};reader.readAsArrayBuffer(chunk);}}跨浏览器进度监控// 统一进度处理functionupdateProgress(fileId,progress){if(window.WebSocket){// WebSocket实时推送constsocketnewWebSocket(ws://your-server/progress);socket.send(JSON.stringify({fileId,progress}));}else{// IE8轮询方案setInterval((){fetch(/api/progress?fileId${fileId}).then(resres.json()).then(data{// 更新UI});},3000);}}五、部署与测试方案测试矩阵浏览器操作系统测试场景IE8Windows 75GB文件上传Chrome 115Windows 1020GB文件夹上传Firefox 115macOS 13中断续传测试Safari 16macOS 13SM4加密下载验证性能优化前端分片大小动态调整根据网络状况并发数限制避免浏览器崩溃后端Nginx配置client_max_body_size 20G; proxy_buffering off;Tomcat配置六、交付成果前端包兼容IE8的Vue3组件库SM4/AES加密工具库WebAssembly优化版测试用例含IE8特殊场景后端包SpringBoot分片处理模块加密存储中间件进度监控服务文档兼容性部署指南安全加固手册性能调优参数表方案价值通过自研核心模块开源组件组合在4周内完成了需求交付相比纯商业方案节省60%成本特别针对政府客户要求的SM4国密算法和IE8兼容性进行了深度优化为后续信创项目积累了可复用的技术资产。SQL示例创建数据库配置数据库连接自动下载maven依赖启动项目启动成功访问及测试默认页面接口定义在浏览器中访问数据表中的数据效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。示例下载下载完整示例