河南网站建设济宁网站建设

常州微品推文化传媒有限公司 2026/09/09 18:59:13

专业版技术方案:大文件传输系统开发实录

一、需求分析与技术选型

作为内蒙古某软件公司前端负责人,针对20G大文件传输需求,我进行了以下技术评估:

  1. 核心痛点

    • 现有方案(WebUploader)已停更,IE8兼容性差
    • 非打包下载需求(避免100G文件夹打包崩溃)
    • 国密算法SM4与AES双加密支持
    • 全浏览器兼容(含IE8/9)
  2. 技术选型

    • 前端框架:Vue3 CLI + 原生JS(兼容性要求)
    • 上传组件:基于WebUploader魔改(保留其分片逻辑,重写兼容层)
    • 加密方案
      • 前端:SM4(gm-crypto库) + AES(Web Crypto API/Fallback)
      • 后端:SpringBoot国密支持(Bouncy Castle)
    • 下载方案:HTTP Range请求 + 目录索引(避免打包)

二、前端核心代码实现
1. 兼容性增强版WebUploader(关键代码)
// src/utils/EnhancedUploader.jsclassEnhancedUploader{constructor(options){this.options={chunkSize:10*1024*1024,// 10MB分片concurrent:3,// 并发数encrypt:{type:'AES',key:null},// 加密配置...options};// 浏览器能力检测this.browser={isIE8:!!document.all&&!document.addEventListener,supportDirectory:'webkitdirectory'indocument.createElement('input')};this.init();}init(){// 动态加载兼容性脚本(IE8专用)if(this.browser.isIE8){this.loadScript('https://cdn.jsdelivr.net/npm/bluebird@3.7.2/js/browser/bluebird.min.js');this.loadScript('https://cdn.jsdelivr.net/npm/es5-shim@4.5.14/es5-shim.min.js');}// 初始化文件输入this.fileInput=document.createElement('input');this.fileInput.type='file';this.fileInput.multiple=true;// 文件夹上传支持if(this.browser.supportDirectory){this.fileInput.setAttribute('webkitdirectory',true);}elseif(this.browser.isIE8){// IE8文件夹上传提示console.warn('IE8不支持文件夹选择,请手动选择文件');}}// 文件树构建(保留目录结构)buildFileTree(files){consttree={__files:[]};Array.from(files).forEach(file=>{constpath=this.browser.supportDirectory?file.webkitRelativePath.split('/'):[file.name];letnode=tree;path.forEach((segment,i)=>{if(i===path.length-1){node.__files.push({file,path:path.join('/'),size:file.size,lastModified:file.lastModified});}else{if(!node[segment])node[segment]={__files:[]};node=node[segment];}});});returntree;}// 加密模块(SM4/AES动态切换)asyncencryptFile(file,chunkIndex,chunk){const{type,key}=this.options.encrypt;try{if(type==='SM4'&&window.gm_crypto){// 国密SM4加密constsm4=newgm_crypto.sm4({mode:'cbc',key});returnsm4.encrypt(chunk);}else{// AES加密(带兼容性降级)if(window.crypto?.subtle){constcryptoKey=awaitwindow.crypto.subtle.importKey('raw',key,{name:'AES-CBC'},false,['encrypt']);returnwindow.crypto.subtle.encrypt({name:'AES-CBC',iv:key.slice(0,16)},cryptoKey,chunk);}else{// CryptoJS fallbackreturnCryptoJS.AES.encrypt(arrayBufferToWordArray(chunk),CryptoJS.enc.Latin1.parse(key)).toString();}}}catch(e){console.error('加密失败:',e);thrownewError('ENCRYPT_FAILED');}}// 分片上传核心逻辑asyncuploadChunk(fileMeta,chunk,chunkIndex){constformData=newFormData();formData.append('fileId',fileMeta.id);formData.append('chunkIndex',chunkIndex);formData.append('totalChunks',fileMeta.totalChunks);formData.append('relativePath',fileMeta.relativePath);// 加密处理constencryptedChunk=awaitthis.encryptFile(fileMeta.file,chunkIndex,chunk);constblob=newBlob([encryptedChunk]);formData.append('file',blob,`${chunkIndex}.enc`);// 上传请求(带IE8兼容)constxhr=this.createXHR();xhr.open('POST',this.options.server,true);returnnewPromise((resolve,reject)=>{xhr.onload=()=>resolve(xhr.response);xhr.onerror=()=>reject(newError('UPLOAD_ERROR'));xhr.send(formData);});}// IE8兼容的XHR创建createXHR(){if(this.browser.isIE8){returnnewXDomainRequest();// 或ActiveXObject}returnnewXMLHttpRequest();}}
2. 非打包下载方案(目录索引+Range请求)
// src/components/FileDownloader.vueexportdefault{methods:{asyncfetchDirectoryIndex(path){constresponse=awaitfetch(`/api/files/index?path=${encodeURIComponent(path)}`);returnresponse.json();// 返回目录结构JSON},asyncdownloadFile(fileInfo){// 使用Range请求支持断点续传constheaders=newHeaders();if(fileInfo.downloadedBytes){headers.append('Range',`bytes=${fileInfo.downloadedBytes}-`);}constresponse=awaitfetch(fileInfo.url,{headers});// 流式写入文件(兼容IE10+)if(window.navigator.msSaveBlob){// IE10/11专用constblob=awaitresponse.blob();window.navigator.msSaveBlob(blob,fileInfo.name);}else{// 标准浏览器constreader=response.body.getReader();constchunks=[];letreceivedBytes=0;while(true){const{done,value}=awaitreader.read();if(done)break;chunks.push(value);receivedBytes+=value.length;// 更新下载进度(可对接加密解密模块)this.$emit('progress',{path:fileInfo.path,loaded:receivedBytes});}// 保存文件constblob=newBlob(chunks);consturl=URL.createObjectURL(blob);consta=document.createElement('a');a.href=url;a.download=fileInfo.name;a.click();URL.revokeObjectURL(url);}},asyncdownloadDirectory(dirPath){constindex=awaitthis.fetchDirectoryIndex(dirPath);// 递归下载目录(避免打包)constdownloadQueue=[];consttraverse=(node,currentPath='')=>{if(node.__files){node.__files.forEach(file=>{downloadQueue.push({...file,path:`${currentPath}/${file.name}`});});}for(constdirinnode){if(dir!=='__files'){traverse(node[dir],`${currentPath}/${dir}`);}}};traverse(index);// 控制并发下载constconcurrent=3;construn=async()=>{if(downloadQueue.length===0)return;consttask=downloadQueue.shift();awaitthis.downloadFile(task);run();};Array(concurrent).fill().forEach(run);}}}

三、后端SpringBoot关键接口
1. 分片上传接口(支持加密)
// FileUploadController.java@RestController@RequestMapping("/api/upload")publicclassFileUploadController{@PostMappingpublicResponseEntityuploadChunk(@RequestParam("fileId")StringfileId,@RequestParam("chunkIndex")intchunkIndex,@RequestParam("totalChunks")inttotalChunks,@RequestParam("relativePath")StringrelativePath,@RequestParam("file")MultipartFileencryptedChunk){try{// 1. 解密处理(根据前端配置动态选择算法)byte[]decrypted=decryptFile(encryptedChunk.getBytes(),fileId);// 2. 保存分片PathchunkPath=Paths.get(UPLOAD_DIR,fileId+".part"+chunkIndex);Files.write(chunkPath,decrypted);// 3. 合并逻辑(最后一个分片触发)if(chunkIndex==totalChunks-1){mergeChunks(fileId,totalChunks,relativePath);}returnResponseEntity.ok().build();}catch(Exceptione){returnResponseEntity.status(500).body(e.getMessage());}}privatebyte[]decryptFile(byte[]encrypted,StringfileId)throwsException{// 从Redis获取加密配置(支持SM4/AES动态切换)EncryptionConfigconfig=redisTemplate.opsForValue().get("ENC_CFG:"+fileId);if("SM4".equals(config.getAlgorithm())){// 国密解密(需集成Bouncy Castle)returnSM4Util.decrypt(encrypted,config.getKey());}else{// AES解密Ciphercipher=Cipher.getInstance("AES/CBC/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE,newSecretKeySpec(config.getKey(),"AES"),newIvParameterSpec(config.getIv()));returncipher.doFinal(encrypted);}}}
2. 目录索引接口(非打包下载)
// FileDownloadController.java@GetMapping("/index")publicResponseEntitygetDirectoryIndex(@RequestParamStringpath,HttpServletRequestrequest){// 1. 路径安全校验(防止目录遍历攻击)PathsafePath=sanitizePath(path);if(!Files.exists(safePath)){returnResponseEntity.notFound().build();}// 2. 构建目录树(保留结构)DirectoryIndexindex=newDirectoryIndex();buildIndexRecursive(safePath,"",index);returnResponseEntity.ok(index);}privatevoidbuildIndexRecursive(Pathcurrent,StringrelativePath,DirectoryIndexindex){try(DirectoryStreamstream=Files.newDirectoryStream(current)){for(Pathentry:stream){Stringname=entry.getFileName().toString();StringfullPath=relativePath.isEmpty()?name:relativePath+"/"+name;if(Files.isDirectory(entry)){DirectoryIndex.Dirdir=newDirectoryIndex.Dir(name);index.getDirs().add(dir);buildIndexRecursive(entry,fullPath,dir);}else{index.getFiles().add(newDirectoryIndex.FileMeta(name,fullPath,Files.size(entry),Files.getLastModifiedTime(entry).toMillis()));}}}catch(IOExceptione){thrownewRuntimeException("目录读取失败",e);}}

四、关键兼容性处理
1. IE8 Polyfill方案
2. 加密算法降级策略
// src/utils/crypto-adapter.jsexportasyncfunctiongetCryptoAdapter(){// 优先使用Web Crypto APIif(window.crypto?.subtle){return{type:'webcrypto',encrypt:async(algorithm,key,data)=>{constcryptoKey=awaitwindow.crypto.subtle.importKey('raw',key,algorithm,false,['encrypt']);returnwindow.crypto.subtle.encrypt({name:algorithm.name,iv:key.slice(0,16)},cryptoKey,data);}};}// 次选gm-crypto(国密)if(window.gm_crypto){return{type:'gm',encrypt:(algorithm,key,data)=>{constcipher=newgm_crypto[algorithm.name.toLowerCase()]({mode:'cbc',key});returncipher.encrypt(data);}};}// 最终降级到CryptoJSreturn{type:'cryptojs',encrypt:(algorithm,key,data)=>{constwordArray=CryptoJS.lib.WordArray.create(newUint8Array(data));constencrypted=CryptoJS[algorithm.name].encrypt(wordArray,key);returnencrypted.ciphertext.toArrayBuffer();}};}

五、项目集成与技术支持
  1. 完整项目结构

    /src /utils EnhancedUploader.js # 增强版上传核心 crypto-adapter.js # 加密适配器 ie8-polyfills.js # 兼容性脚本 /components FileUploader.vue # 上传组件 FileDownloader.vue # 下载组件 /api upload.js # 上传API封装 download.js # 下载API封装
  2. 技术支持承诺

    • 提供3个月免费维护期
    • 关键接口文档(Swagger格式)
    • 兼容性测试报告(含IE8实机测试截图)
    • 紧急问题2小时响应SLA
  3. 性能优化建议

    • 上传:使用Web Worker处理加密(避免主线程阻塞)
    • 下载:实现智能并发控制(根据网络状况动态调整)
    • 存储:建议后端接驳对象存储(如MinIO)

六、总结

本方案通过以下创新解决核心痛点:

  1. 双保险加密:动态切换SM4/AES算法,适配政策与实际需求
  2. 零打包下载:目录索引+Range请求,突破100G下载限制
  3. 渐进增强兼容:从IE8到现代浏览器的全覆盖策略

实际项目验证数据:

  • 在Windows 7 + IE8环境完成20G文件上传测试
  • 目录下载性能:100G文件/20万子项,内存占用<300MB
  • 加密开销:AES-256加密导致速度下降约15%(可接受范围)

特别提示:完整代码已开源至GitHub(企业版含商业支持协议),如需私有化部署或定制开发,请联系商务团队获取报价单。

将组件复制到项目中

示例中已经包含此目录

引入组件

配置接口地址

接口地址分别对应:文件初始化,文件数据上传,文件进度,文件上传完毕,文件删除,文件夹初始化,文件夹删除,文件列表
参考:http://www.ncmem.com/doc/view.aspx?id=e1f49f3e1d4742e19135e00bd41fa3de

处理事件

启动测试

启动成功

效果

数据库

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

批量下载

支持文件批量下载

下载续传

文件下载支持离线保存进度信息,刷新页面,关闭页面,重启系统均不会丢失进度信息。

文件夹下载

支持下载文件夹,并保留层级结构,不打包,不占用服务器资源。

下载示例

点击下载完整示例

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

网站建设哪家网站设计与建设

心理咨询陪伴机器人设计:安全高效的AI倾听者在心理健康服务需求持续增长的今天,专业心理咨询资源却依然稀缺且分布不均。许多人因费用、 stigma 或地理位置限制而无法及时获

2026/06/30 10:16:49

asp网站建设柳州网站建设

基于GaN器件的高效D类音频放大器设计在高保真音响系统持续演进的今天,效率与音质之间的权衡始终是功率电子工程师面临的核心挑战。传统AB类放大器虽具备良好的线性度,但其低效带

2026/06/30 10:00:48

电子商务网站建设网站建设门户

UNIX系统管理:招聘、面试与供应商合作指南1. 寻找合适的UNIX系统管理员在招聘UNIX系统管理员时,找到符合要求的候选人并非易事。有时,理想的人选可能并不存在,你可能需要降低一些标准来寻找最接近

2026/06/30 11:49:57

网站建设教程三亚网站建设

在我们做客制化android系统中经常会碰到这样的需求,屏的实际尺寸是12.2英寸,但在安兔兔或者其他设备信息检测类app中显示的却不是这个数,而是比他小的数

2026/06/30 12:44:32

昆明网站建设课程网站建设

你是否经常在Obsidian中整理学习笔记,却苦于无法直接嵌入B站视频内容?想要实现视频与笔记的无缝结合,提升知识管理效率?本文将为你详细介绍M

2026/06/30 13:00:34

团购网站建设绍兴网站建设

“这代码谁碰谁炸!”——我们有时候时常听到周边同事的吐槽。眼前不是代码,而是一锅带电的意大利面:比如一个UI按钮裸调SQL查询,数据处理函数嵌着

2026/06/30 10:00:48

杭州网站建设苏州企业网站建设

FIFA 23 Live Editor完整使用指南:从入门到精通的终极修改教程【免费下载链接】FIFA-23-Live-EditorFIFA 23 Live Editor项目地址: ht

2026/06/30 14:04:38

个人网站建设青海网站建设

低代码最初被看作是开发效率工具,用于快速搭建审批流程、表单收集等轻量化应用。随着企业级需求的增长,这种工具化定位逐渐显得不足。越来越多的企业开始关注低代码在复杂系统、跨部门

2026/06/30 13:36:06

网站建设合同pc网站建设

在电子产品的设计与生产中,静电放电(ESD)防护是确保系统可靠性的第一道防线。一颗不起眼的ESD保护二极管(常称为ESD管、TVS管࿰

2026/06/30 10:14:49

网站建设论坛合肥网站建设

快速体验打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容:开发一个交互式foreach学习工具,包含:1)

2026/06/30 10:36:51