news 2026/1/28 18:30:45

分享三种网页文件上传下载的解决方案及其实现思路?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
分享三种网页文件上传下载的解决方案及其实现思路?

📅 开发者日志:大文件上传系统的艰难实现之路

项目背景

2023年11月15日,周三,晴转多云

今天正式接手了一个具有挑战性的外包项目——构建一个支持20GB超大文件传输的Web系统。客户要求苛刻但预算有限,作为一名个人开发者,这既是一次机遇也是巨大的挑战。

需求分析

核心功能需求

  1. 超大文件支持:单文件20GB传输
  2. 批量传输:包含上千文件的文件夹层级结构保持
  3. 安全要求:SM4/AES加密传输与存储
  4. 稳定性:断点续传需持久化保存进度
  5. 兼容性:必须支持IE8等老旧浏览器

技术栈确认

  • 前端:Vue3 + WebUploader/原生H5
  • 后端:ASP.NET Core (.NET 8)
  • 数据库:SQL Server
  • 存储:阿里云OSS
  • 跨平台支持:Windows/macOS/Linux全平台

技术难点突破

文件夹结构保持方案

// 文件夹上传处理逻辑classFolderUploader{constructor(){this.folderStructure=newMap();// 使用Map保存完整路径}processEntry(entry,path=''){returnnewPromise((resolve)=>{if(entry.isFile){entry.file(file=>{constfullPath=`${path}/${file.name}`;this.folderStructure.set(fullPath,file);resolve();});}elseif(entry.isDirectory){constdirReader=entry.createReader();dirReader.readEntries(entries=>{constpromises=entries.map(subEntry=>this.processEntry(subEntry,`${path}/${entry.name}`));Promise.all(promises).then(resolve);});}});}}

断点续传持久化方案

// ASP.NET Core 断点续传状态管理publicclassUploadStateService{privatereadonlyConcurrentDictionary_stateCache;publicUploadStateService(){_stateCache=newConcurrentDictionary();}publicvoidSaveState(stringfileId,longchunkIndex){varstate=_stateCache.GetOrAdd(fileId,id=>newUploadState(id));state.UploadedChunks.Add(chunkIndex);// 持久化到数据库usingvardb=newAppDbContext();db.UploadStates.Update(state.ToEntity());db.SaveChanges();}publicUploadStateGetState(stringfileId){if(_stateCache.TryGetValue(fileId,outvarstate)){returnstate;}// 从数据库加载usingvardb=newAppDbContext();varentity=db.UploadStates.Find(fileId);returnentity?.ToModel()??newUploadState(fileId);}}

前后端完整交互示例

前端加密上传实现

// 基于WebUploader的加密上传组件exportclassSecureFileUploader{constructor(options){this.uploader=WebUploader.create({swf:'/libs/Uploader.swf',server:options.uploadUrl,chunked:true,chunkSize:4*1024*1024,// 4MB分片threads:3,prepareNextFile:true,fileSizeLimit:20*1024*1024*1024// 20GB});this.initEvents();this.cryptoWorker=newWorker('/js/crypto.worker.js');}initEvents(){this.uploader.on('uploadBeforeSend',(obj,data)=>{returnnewPromise(resolve=>{this.cryptoWorker.postMessage({type:'encrypt',data:obj.file,algorithm:'SM4'});this.cryptoWorker.onmessage=(e)=>{data.file=e.data;resolve(data);};});});this.uploader.on('fileQueued',file=>{conststate=localStorage.getItem(`upload_${file.id}`);if(state){this.uploader.uploader.upload(file,JSON.parse(state));}});}}

后端分片处理实现

// ASP.NET Core 文件分片控制器[ApiController][Route("api/upload")]publicclassUploadController:ControllerBase{privatereadonlyUploadStateService_stateService;privatereadonlyIOSSClient_ossClient;publicUploadController(UploadStateServicestateService,IOSSClientossClient){_stateService=stateService;_ossClient=ossClient;}[HttpPost("chunk")]publicasyncTaskUploadChunk([FromForm]IFormFilefile,[FromForm]stringfileId,[FromForm]intchunkIndex,[FromForm]inttotalChunks){usingvarmemoryStream=newMemoryStream();awaitfile.CopyToAsync(memoryStream);// 解密处理vardecryptedData=CryptoHelper.SM4Decrypt(memoryStream.ToArray(),Configuration["EncryptionKey"]);// 存储到OSSvarchunkKey=$"{fileId}/{chunkIndex}";await_ossClient.PutObjectAsync("uploads",chunkKey,newMemoryStream(decryptedData));// 更新状态_stateService.SaveState(fileId,chunkIndex);if(chunkIndex==totalChunks-1){// 触发文件合并BackgroundJob.Enqueue(()=>MergeFileChunks(fileId));}returnOk(new{success=true});}[NonAction]publicasyncTaskMergeFileChunks(stringfileId){varstate=_stateService.GetState(fileId);varfinalKey=$"files/{DateTime.Now:yyyyMMdd}/{fileId}";usingvarfinalStream=newMemoryStream();foreach(varchunkinstate.UploadedChunks.OrderBy(x=>x)){varchunkKey=$"{fileId}/{chunk}";varchunkData=await_ossClient.GetObjectAsync("uploads",chunkKey);awaitchunkData.CopyToAsync(finalStream);await_ossClient.DeleteObjectAsync("uploads",chunkKey);}finalStream.Position=0;await_ossClient.PutObjectAsync("final",finalKey,finalStream);}}

兼容性处理方案

IE8兼容层实现

// ie8-wrapper.js(function(){// Polyfill for File APIif(!window.File){window.File=function(){};window.FileReader=function(){this.readAsArrayBuffer=function(blob){// IE8的ActiveX实现varaxo=newActiveXObject("ADODB.Stream");axo.Type=1;// 二进制类型axo.Open();axo.LoadFromFile(blob.name);varbuffer=axo.Read();this.onload({target:{result:buffer}});};};}// Polyfill for FormDataif(!window.FormData){window.FormData=function(){this.append=function(key,value){// 使用隐藏iframe实现表单提交variframe=document.createElement('iframe');iframe.name='formdata-iframe';document.body.appendChild(iframe);varform=document.createElement('form');form.target=iframe.name;form.method='POST';form.enctype='multipart/form-data';varinput=document.createElement('input');input.type='hidden';input.name=key;input.value=value;form.appendChild(input);document.body.appendChild(form);form.submit();};};}})();

开发文档结构

📂 项目文档 ├── 1. 系统架构设计 │ ├── 1.1 技术栈说明 │ ├── 1.2 系统架构图 │ └── 1.3 部署拓扑图 ├── 2. API接口文档 │ ├── 2.1 上传接口规范 │ ├── 2.2 下载接口规范 │ └── 2.3 状态管理接口 ├── 3. 前端集成指南 │ ├── 3.1 WebUploader配置 │ ├── 3.2 加密模块使用 │ └── 3.3 兼容性处理 ├── 4. 后端部署手册 │ ├── 4.1 环境配置 │ ├── 4.2 数据库初始化 │ └── 4.3 性能调优 └── 5. 运维监控 ├── 5.1 日志收集 ├── 5.2 异常告警 └── 5.3 扩容方案

项目总结

已解决问题

  1. 通过分片加密上传实现了20GB文件支持
  2. 使用目录树遍历算法保持文件夹结构
  3. 结合本地存储和数据库实现持久化断点续传
  4. 开发多套降级方案保证IE8兼容性

待解决问题

  1. 极端网络环境下分片成功率优化
  2. OSS批量操作的性能瓶颈
  3. 国产浏览器(红莲花等)的特殊适配

后记:这个项目让我深刻体会到企业级文件传输的复杂性。欢迎同行加入QQ群374992201交流大文件传输技术,共同应对外包项目中的各种挑战。

设置框架

安装.NET Framework 4.7.2
https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472
框架选择4.7.2

添加3rd引用

编译项目

NOSQL

NOSQL无需任何配置可直接访问页面进行测试

SQL

使用IIS
大文件上传测试推荐使用IIS以获取更高性能。

使用IIS Express

小文件上传测试可以使用IIS Express

创建数据库

配置数据库连接信息

检查数据库配置

访问页面进行测试


相关参考:
文件保存位置,

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

下载完整示例

下载完整示例

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

【Django毕设全套源码+文档】django基于协同过滤的音乐推荐系统的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/1/25 12:08:32

BSHM镜像支持CUDA11.3,40系显卡用户福音

BSHM镜像支持CUDA11.3,40系显卡用户福音 如果你正为RTX 4090、4080或4070显卡上跑不动人像抠图模型而发愁,今天这个消息值得你停下来看完——BSHM人像抠图模型镜像正式支持CUDA 11.3,彻底打通40系显卡的推理链路。不用降级驱动,不…

作者头像 李华
网站建设 2026/1/28 1:42:27

小区充电桩智能监控

目录小区充电桩智能监控的基本概念核心功能技术实现应用优势源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!小区充电桩智能监控的基本概念 小区充电桩智能监控系统通过物联网技术、大数据分析和远程管理平台,实现对充电桩运…

作者头像 李华
网站建设 2026/1/25 12:05:18

航空航天网页项目,文件上传下载有哪些高效的解决方案?

政府项目大文件传输系统开发方案 一、技术选型与架构设计 作为项目技术负责人,针对政府招投标系统的特殊需求,设计以下技术方案: 1.1 核心架构 #mermaid-svg-5Hqv1JWNT4R0Gdz0{font-family:"trebuchet ms",verdana,arial,sans-s…

作者头像 李华
网站建设 2026/1/28 15:58:25

TurboDiffusion实战对比:Wan2.1与Wan2.2视频生成性能全面评测

TurboDiffusion实战对比:Wan2.1与Wan2.2视频生成性能全面评测 1. 什么是TurboDiffusion?它为什么值得你花时间了解 TurboDiffusion不是又一个“概念验证”项目,而是真正能跑在单张消费级显卡上的视频生成加速框架。它由清华大学、生数科技和…

作者头像 李华
网站建设 2026/1/28 9:52:53

小白也能懂:用Qwen3-Embedding-0.6B快速实现文本向量化

小白也能懂:用Qwen3-Embedding-0.6B快速实现文本向量化 你有没有遇到过这样的问题: 想让搜索更准,却不知道怎么让“苹果手机”和“iPhone”自动关联? 想给客服机器人加知识库,但一堆文档没法直接喂给模型?…

作者头像 李华