内网环境下,html5如何支持大文件的分块上传?
中石油旗下子公司大文件传输系统技术方案一、项目背景与需求分析作为中石油集团旗下专注于能源信息化领域的子公司我司长期服务于政府及军工单位在能源管理、安全生产等关键领域积累了丰富的行业经验。本次政府招投标项目提出的大文件传输需求具有以下特殊性功能需求支持20GB以上超大文件传输支持文件夹结构上传/下载保持目录层级支持断点续传、分片校验、传输加密支持传输队列管理优先级控制兼容性要求主流浏览器Chrome/Firefox/Edge/国产浏览器信创国产化环境麒麟/统信UOS 飞腾/鲲鹏/龙芯数据库兼容性SQL Server/达梦/人大金仓技术架构约束后端ASP.NET Framework 4.8暂不考虑.NET Core迁移前端ASP.NET WebForms需兼容IE11及现代浏览器需提供完整源代码及知识产权特殊需求军工级安全要求等保三级传输过程不可逆加密详细的操作审计日志二、现有方案评估2.1 已评估开源方案组件名称优点缺点WebUploader成熟度高已停更最后更新2018年不支持信创环境Fine Uploader商业级功能许可证成本高定制开发受限Dropzone.js简单易用仅支持基础上传缺乏大文件处理能力Plupload多后端支持文档陈旧.NET实现效率低2.2 核心问题信创环境兼容性现有组件均未针对国产CPU架构和操作系统进行优化技术架构限制ASP.NET WebForms的异步处理能力有限安全合规性开源组件缺乏军工级加密和审计功能文件夹支持大多数组件仅支持单文件上传三、自研组件技术方案3.1 架构设计┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │ ASP.NET WebForms │ │ IIS (WebDAV) │ │ WCF/ASP.NET服务 │ │ (前端上传控件) │←──→│ (静态资源代理) │←──→│ (传输处理服务) │ └─────────────────────┘ └─────────────────────┘ └─────────────────────┘ ↑ ↑ ↑ HTML5 File API SignalR实时通知 ADO.NET多数据库适配 (Folder API polyfill) (传输进度推送) (SQL Server/达梦/人大金仓)3.2 核心代码实现前端实现ASP.NET WebForms控件// FileTransferControl.ascx.cspublicpartialclassFileTransferControl:System.Web.UI.UserControl{protectedvoidPage_Load(objectsender,EventArgse){if(!IsPostBack){RegisterClientScripts();}}privatevoidRegisterClientScripts(){stringscript // 文件夹选择兼容性处理IE11现代浏览器 function handleFolderSelect(event) { const input event.target; if (input.files input.files.length 0) { processFiles(input.files); } } // 分片上传核心逻辑 async function uploadFile(file, options) { const chunkSize 10 * 1024 * 1024; // 10MB分片 const chunks Math.ceil(file.size / chunkSize); let uploadedChunks 0; // 计算文件SM3哈希国产密码算法 const fileHash await calculateSM3Hash(file); // 检查文件是否已存在 const checkResult await $.ajax({ url: FileTransferHandler.ashx?actioncheck, type: POST, data: { fileName: file.name, fileSize: file.size, fileHash } }); if (checkResult.exists) { showProgress(file.name, 100); return; } // 分片上传 for (let i 0; i chunks; i) { const start i * chunkSize; const end Math.min(start chunkSize, file.size); const chunk file.slice(start, end); const formData new FormData(); formData.append(file, chunk); formData.append(fileId, options.fileId); formData.append(chunkIndex, i); formData.append(totalChunks, chunks); formData.append(fileHash, fileHash); formData.append(relativePath, options.relativePath || ); await $.ajax({ url: FileTransferHandler.ashx?actionupload, type: POST, data: formData, processData: false, contentType: false, xhr: function() { const xhr new XMLHttpRequest(); xhr.upload.addEventListener(progress, function(e) { if (e.lengthComputable) { const progress Math.round( (uploadedChunks * chunkSize e.loaded) / file.size * 100 ); showProgress(file.name, progress); } }, false); return xhr; } }); uploadedChunks; } // 通知服务器合并 await $.ajax({ url: FileTransferHandler.ashx?actionmerge, type: POST, data: { fileId: options.fileId, fileHash, totalChunks: chunks, originalName: file.name, relativePath: options.relativePath } }); showProgress(file.name, 100); } // SM3哈希计算通过Web Worker function calculateSM3Hash(file) { return new Promise((resolve) { const worker new Worker(/Scripts/sm3.worker.js); worker.postMessage({ file }); worker.onmessage (e) resolve(e.data.hash); }); };ScriptManager.RegisterStartupScript(this,GetType(),FileTransferScript,script,true);}protectedvoidbtnUpload_Click(objectsender,EventArgse){// 服务器端初始化上传会话stringsessionIdGuid.NewGuid().ToString();Session[FileTransfer_sessionId]newFileTransferSession{StartTimeDateTime.Now,UserIdUser.Identity.Name,ClientIPRequest.UserHostAddress};hdnSessionId.ValuesessionId;}}后端实现ASP.NET通用处理程序// FileTransferHandler.ashx.cspublicclassFileTransferHandler:IHttpHandler{privatereadonlyIFileStorageService_storageService;privatereadonlyIAuditLogService_auditLog;publicFileTransferHandler(){// 通过依赖注入或服务定位器获取服务_storageServiceServiceLocator.Current.GetInstance();_auditLogServiceLocator.Current.GetInstance();}publicvoidProcessRequest(HttpContextcontext){context.Response.ContentTypeapplication/json;try{varactioncontext.Request[action];varsessionIdcontext.Request[sessionId]??context.Request.Cookies[FileTransferSession];varsessioncontext.Session[FileTransfer_sessionId]asFileTransferSession;if(sessionnull){thrownewInvalidOperationException(无效的传输会话);}switch(action?.ToLower()){casecheck:HandleCheckRequest(context,session);break;caseupload:HandleUploadRequest(context,session);break;casemerge:HandleMergeRequest(context,session);break;casedownload:HandleDownloadRequest(context,session);break;default:thrownewNotSupportedException(不支持的操作);}}catch(Exceptionex){context.Response.StatusCode500;context.Response.Write(JsonConvert.SerializeObject(new{successfalse,messageex.Message}));// 记录错误日志_auditLog.LogError(FileTransfer,ex.ToString(),context.Request.UserHostAddress,User.Identity.Name);}}privatevoidHandleCheckRequest(HttpContextcontext,FileTransferSessionsession){varfileNamecontext.Request[fileName];varfileSizelong.Parse(context.Request[fileSize]);varfileHashcontext.Request[fileHash];// 多数据库适配查询varexists_storageService.CheckFileExists(fileHash,fileSize);context.Response.Write(JsonConvert.SerializeObject(new{successtrue,exists,fileIdGuid.NewGuid().ToString()}));// 记录审计日志_auditLog.LogAccess(FileCheck,${fileName}({fileSize}bytes),context.Request.UserHostAddress,User.Identity.Name);}privatevoidHandleUploadRequest(HttpContextcontext,FileTransferSessionsession){if(context.Request.Files.Count0){thrownewArgumentException(未接收到文件数据);}varfilecontext.Request.Files[0];varfileIdcontext.Request[fileId];varchunkIndexint.Parse(context.Request[chunkIndex]);vartotalChunksint.Parse(context.Request[totalChunks]);varfileHashcontext.Request[fileHash];varrelativePathcontext.Request[relativePath];// 临时存储路径按会话ID分目录vartempPathPath.Combine(_storageService.TempDirectory,fileId);Directory.CreateDirectory(tempPath);varchunkPathPath.Combine(tempPath,$chunk-{chunkIndex});file.SaveAs(chunkPath);// 记录分片上传日志数据库适配using(vardbDatabaseFactory.CreateDatabase()){db.ExecuteNonQuery(INSERT INTO FileTransferChunks (FileId, ChunkIndex, Size, UploadTime) VALUES (fileId, chunkIndex, size, GETDATE()),fileId,chunkIndex,file.ContentLength);}context.Response.Write(JsonConvert.SerializeObject(new{successtrue,chunkIndex,receivedSizefile.ContentLength}));}// 其他处理方法...}多数据库适配层// DatabaseFactory.cspublicstaticclassDatabaseFactory{privatestaticreadonlystring_dbTypeConfigurationManager.AppSettings[DatabaseType];publicstaticIDatabaseCreateDatabase(){switch(_dbType?.ToUpper()){caseDM:returnnewDamengDatabaseAdapter();caseKINGBASE:returnnewKingbaseDatabaseAdapter();caseSQLSERVER:default:returnnewSqlServerDatabaseAdapter();}}}publicinterfaceIDatabase:IDisposable{intExecuteNonQuery(stringsql,paramsobject[]parameters);objectExecuteScalar(stringsql,paramsobject[]parameters);DataTableExecuteDataTable(stringsql,paramsobject[]parameters);}// SQL Server实现publicclassSqlServerDatabaseAdapter:IDatabase{privateSqlConnection_connection;publicSqlServerDatabaseAdapter(){_connectionnewSqlConnection(ConfigurationManager.ConnectionStrings[SqlServer].ConnectionString);_connection.Open();}publicintExecuteNonQuery(stringsql,paramsobject[]parameters){using(varcmdnewSqlCommand(sql,_connection)){cmd.Parameters.AddRange(parameters.Select((p,i)newSqlParameter($param{i},p??DBNull.Value)).ToArray());returncmd.ExecuteNonQuery();}}// 其他方法实现...publicvoidDispose(){_connection?.Dispose();}}// 达梦数据库实现publicclassDamengDatabaseAdapter:IDatabase{privateDmConnection_connection;publicDamengDatabaseAdapter(){_connectionnewDmConnection(ConfigurationManager.ConnectionStrings[Dameng].ConnectionString);_connection.Open();}publicintExecuteNonQuery(stringsql,paramsobject[]parameters){// 达梦特定语法适配sqlsql.Replace(GETDATE(),SYSDATE).Replace([,\).Replace(],\);using(varcmdnewDmCommand(sql,_connection)){cmd.Parameters.AddRange(parameters.Select((p,i)newDmParameter($:param{i},p??DBNull.Value)).ToArray());returncmd.ExecuteNonQuery();}}// 其他方法实现...}3.3 信创环境适配方案国产密码算法集成// SM3哈希计算通过P/Invoke调用国产密码库publicstaticclassSM3Helper{[DllImport(GMSSL.dll,EntryPointSM3_Compute,CharSetCharSet.Ansi)]privatestaticexternintNativeSM3Compute(byte[]input,intinputLen,byte[]output);publicstaticstringComputeHash(Streamstream){constintbufferSize8192;byte[]buffernewbyte[bufferSize];intbytesRead;using(varsm3SM3.Create())// 使用BouncyCastle的SM3实现或国产密码库{while((bytesReadstream.Read(buffer,0,bufferSize))0){sm3.TransformBlock(buffer,0,bytesRead,null,0);}sm3.TransformFinalBlock(buffer,0,0);returnBitConverter.ToString(sm3.Hash).Replace(-,).ToLower();}}}国产操作系统文件系统优化publicclassKylinFileOptimizer:IFileOptimizer{publicvoidOptimizeFileHandle(FileInfofile){if(IsKylinOS()){// 调用国产文件系统特性NativeMethods.SetFileAttribute(file.FullName,FileAttributes.KylinOptimized);}}privateboolIsKylinOS(){returnDirectory.Exists(/etc/kylin)||Directory.Exists(/usr/lib/kylin);}}Web服务器配置四、实施路线图第一阶段6周完成核心传输功能开发实现文件夹结构解析与重建完成SQL Server基础版本第二阶段4周达梦/人大金仓数据库适配信创环境专项优化军工级安全加固第三阶段2周性能调优与压力测试操作手册与API文档编写知识产权梳理与源代码审计五、预期收益完全自主可控掌握全部源代码适应军工项目特殊要求多数据库支持无缝切换SQL Server/达梦/人大金仓信创环境优化针对国产软硬件环境深度优化安全合规满足等保三级要求集成国产密码算法性能提升通过分片并行传输充分利用网络带宽我司已组建由.NET资深专家领衔的专项团队整合集团内部密码技术资源预计在3个月内完成符合军工标准的大文件传输系统开发。该系统不仅满足当前项目需求更可打造为能源行业信创解决方案的核心组件。将组件复制到项目中示例中已经包含此目录引入组件配置接口地址接口地址分别对应文件初始化文件数据上传文件进度文件上传完毕文件删除文件夹初始化文件夹删除文件列表参考http://www.ncmem.com/doc/view.aspx?ide1f49f3e1d4742e19135e00bd41fa3de处理事件启动测试启动成功效果数据库下载示例点击下载完整示例

相关新闻

代码随想录算法训练营第二十五天| 455.分发饼干、376. 摆动序列、53. 最大子序和

代码随想录算法训练营第二十五天| 455.分发饼干、376. 摆动序列、53. 最大子序和

455.分发饼干 目标: g[i]:第 i 个孩子的胃口值(至少要这么大的饼干才满足)s[j]:第 j 块饼干的尺寸 每个孩子最多一块饼干、每块饼干最多给一个孩子。 问最多能满足多少孩子。 核心思路:贪心 排序 双指…

2026/7/6 17:30:57 阅读更多 →
发票红章盖住金额怎么办

发票红章盖住金额怎么办

财务人员在日常工作中,常常遇到一个让人头疼的问题:发票上的红色印章不小心盖到了金额区域,导致关键数字被遮挡。这种情况到底能不能用?又该如何处理?本文将从实务操作和技术解决方案两个角度,帮你彻底搞定…

2026/7/6 7:28:46 阅读更多 →
非标准格式票据怎么录入

非标准格式票据怎么录入

财务人员最头疼的事情之一,莫过于面对一堆格式各异的票据——海外发票、手写单据、各种非标准版式的凭证,传统手工录入不仅耗时费力,还极易出错。随着AI多模态技术的成熟,合合信息推出的TextIn票据识别工具正在改变这一困境&#…

2026/7/3 14:53:12 阅读更多 →

最新新闻

Recog指纹库详解:30+协议类型与匹配场景全解析

Recog指纹库详解:30+协议类型与匹配场景全解析

Recog指纹库详解:30协议类型与匹配场景全解析 【免费下载链接】recog Pattern recognition for hosts, services, and content 项目地址: https://gitcode.com/gh_mirrors/re/recog Recog是一个强大的指纹识别框架,专门用于通过模式匹配技术识别网…

2026/7/6 17:31:15 阅读更多 →
分析报告】量身定制:基于大数据的行业痛点与蓝海机遇挖掘

分析报告】量身定制:基于大数据的行业痛点与蓝海机遇挖掘

【分析报告】量身定制:基于大数据的行业痛点与蓝海机遇挖掘 深夜,你盯着电脑屏幕上密密麻麻的行业数据,从国家统计局到各大咨询公司的白皮书,资料下载了十几个G,PPT做了几十页,但老板那句“所以&#xff0…

2026/7/6 17:27:07 阅读更多 →
ReVanced Integrations 完全指南:掌握 YouTube 增强插件的核心组件库

ReVanced Integrations 完全指南:掌握 YouTube 增强插件的核心组件库

ReVanced Integrations 完全指南:掌握 YouTube 增强插件的核心组件库 【免费下载链接】revanced-integrations 🔩 ReVanced Integrations containing classes to be merged by ReVanced Patcher 项目地址: https://gitcode.com/gh_mirrors/re/revanced…

2026/7/6 17:27:07 阅读更多 →
Redis-Lua在Web开发中的应用:构建高性能Lua后端服务的实战案例

Redis-Lua在Web开发中的应用:构建高性能Lua后端服务的实战案例

Redis-Lua在Web开发中的应用:构建高性能Lua后端服务的实战案例 【免费下载链接】redis-lua A Lua client library for the redis key value storage system. 项目地址: https://gitcode.com/gh_mirrors/re/redis-lua Redis-Lua是一个纯Lua编写的Redis客户端库…

2026/7/6 17:24:58 阅读更多 →
如何快速集成SourceEditor到你的iOS应用:从安装到基础使用的完整指南

如何快速集成SourceEditor到你的iOS应用:从安装到基础使用的完整指南

如何快速集成SourceEditor到你的iOS应用:从安装到基础使用的完整指南 【免费下载链接】source-editor A native source editor for iOS and macOS, written in Swift 项目地址: https://gitcode.com/gh_mirrors/so/source-editor SourceEditor是一个专为iOS和…

2026/7/6 17:24:57 阅读更多 →
5个关键问题:为什么Python开发者需要Neomodel来高效操作Neo4j图数据库

5个关键问题:为什么Python开发者需要Neomodel来高效操作Neo4j图数据库

5个关键问题:为什么Python开发者需要Neomodel来高效操作Neo4j图数据库 【免费下载链接】neomodel An Object Graph Mapper (OGM) for the Neo4j graph database. 项目地址: https://gitcode.com/gh_mirrors/ne/neomodel Neomodel是Neo4j图数据库的官方推荐Py…

2026/7/6 17:22:56 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻