news 2026/9/3 5:08:19

教育行业网页大文件上传插件如何支持断点续传和视频切片?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
教育行业网页大文件上传插件如何支持断点续传和视频切片?

开发者日记:2023年X月X日 星期X 长沙 晴

项目背景
今日正式启动客户的大文件传输系统项目,需求明确:支持20G文件/文件夹上传下载、跨平台(Windows/macOS/Linux)、全浏览器兼容(含IE8)、断点续传、保留文件夹层级结构。后端使用**.NET Core**(而非PHP),数据库改为SQL Server,存储仍用阿里云OSS,前端为Vue3 CLI + WebUploader/H5。客户强调高频文件夹上传场景,需极致优化用户体验。免费开源代码和7*24支持的压力依旧,但技术栈调整带来新挑战。


技术选型与调整

  1. 前端框架

    • Vue3 CLI:维持组件化开发,但需适配IE8的Polyfill(如babel-polyfill)。
    • WebUploader:核心上传组件,需深度定制文件夹解析逻辑。
    • H5 File API:现代浏览器备用方案,IE8回退到Flash上传。
  2. 后端架构

    • .NET Core:替代PHP,利用IFormFile处理分片,System.Data.SqlClient操作SQL Server。
    • SQL Server:存储文件元数据(路径、分片状态、用户ID)。
  3. 核心难点升级

    • 高频文件夹上传:需优化递归解析性能,避免前端卡顿。
    • 断点续传稳定性:SQL Server事务保证分片记录一致性。
    • IE8兼容性:Flash上传需处理跨域问题(crossdomain.xml)。

前端代码优化(Vue3 + WebUploader)

1. 强化文件夹上传逻辑
// src/components/FolderUploader.vueimport{ref,onMounted}from'vue';importWebUploaderfrom'webuploader';import'webuploader/dist/webuploader.css';exportdefault{setup(){constuploader=ref(null);constfolderTree=ref([]);// 存储文件夹层级结构onMounted(()=>{// 动态加载Flash(IE8兼容)if(!WebUploader.Uploader.support('HTML5')){WebUploader.Uploader.register({name:'flash',fn:()=>'/assets/Uploader.swf'});}uploader.value=newWebUploader.Uploader({swf:'/assets/Uploader.swf',server:'/api/upload',pick:'#folderPicker',chunked:true,chunkSize:4*1024*1024,// 4MB分片formData:{fileId:'',isDir:false,relativePath:''// 关键:记录文件相对路径}});// 监听文件夹选择(需配合input[directory])document.getElementById('folderInput').addEventListener('change',(e)=>{constitems=e.target.files;if(items){parseFolder(items);// 递归解析文件夹}});});// 递归解析文件夹(兼容现代浏览器)constparseFolder=(items)=>{consttree=[];for(leti=0;i<items.length;i++){constfile=items[i];constpath=file.webkitRelativePath||file.name;// 相对路径constsegments=path.split('/');// 构建树形结构letcurrentLevel=tree;segments.slice(0,-1).forEach(segment=>{letdir=currentLevel.find(item=>item.name===segment);if(!dir){dir={name:segment,type:'directory',children:[]};currentLevel.push(dir);}currentLevel=dir.children;});// 添加文件节点currentLevel.push({name:segments.pop(),type:'file',file:file,relativePath:path});}folderTree.value=tree;uploadFolder(tree);};// 上传文件夹内容constuploadFolder=(tree)=>{tree.forEach(node=>{if(node.type==='directory'){uploadFolder(node.children);// 递归上传子目录}else{constformData=uploader.value.option('formData');formData.relativePath=node.relativePath;uploader.value.addFile(node.file,node.relativePath);}});};return{uploader,folderTree};}};
2. IE8兼容性处理

后端代码实现(.NET Core + SQL Server)

1. 分片上传接口
// Controllers/UploadController.csusingMicrosoft.AspNetCore.Mvc;usingSystem.Data.SqlClient;usingSystem.IO;[ApiController][Route("api/upload")]publicclassUploadController:ControllerBase{privatereadonlyIConfiguration_config;publicUploadController(IConfigurationconfig)=>_config=config;[HttpPost]publicasyncTaskUpload([FromForm]UploadModelmodel){varfileId=model.FileId??Guid.NewGuid().ToString();vartempDir=Path.Combine("/tmp/uploads",fileId);Directory.CreateDirectory(tempDir);// 保存分片varchunkPath=Path.Combine(tempDir,$"chunk_{model.ChunkIndex}");using(varstream=newFileStream(chunkPath,FileMode.Create)){awaitmodel.File.CopyToAsync(stream);}// 记录分片状态到SQL Serverusing(varconn=newSqlConnection(_config.GetConnectionString("Default"))){awaitconn.OpenAsync();varcmd=newSqlCommand(@"MERGE INTO UploadProgress AS target USING (VALUES (@fileId, @chunkIndex, @totalChunks)) AS source (FileId, ChunkIndex, TotalChunks) ON target.FileId = source.FileId AND target.ChunkIndex = source.ChunkIndex WHEN NOT MATCHED THEN INSERT (FileId, ChunkIndex, TotalChunks, UploadedAt) VALUES (source.FileId, source.ChunkIndex, source.TotalChunks, GETDATE());",conn);cmd.Parameters.AddWithValue("@fileId",fileId);cmd.Parameters.AddWithValue("@chunkIndex",model.ChunkIndex);cmd.Parameters.AddWithValue("@totalChunks",model.TotalChunks);awaitcmd.ExecuteNonQueryAsync();}// 如果是最后一块,合并并上传OSSif(model.ChunkIndex==model.TotalChunks-1){varfinalPath=Path.Combine(tempDir,"final_file");using(varoutput=System.IO.File.Create(finalPath)){for(inti=0;i<model.TotalChunks;i++){varchunk=System.IO.File.ReadAllBytes(Path.Combine(tempDir,$"chunk_{i}"));awaitoutput.WriteAsync(chunk,0,chunk.Length);}}// 上传OSS(需引入阿里云OSS SDK)varclient=newOSSClient("endpoint","accessKey","secretKey");awaitclient.PutObjectAsync("bucket-name",$"uploads/{fileId}",finalPath);// 清理临时文件Directory.Delete(tempDir,true);}returnOk(new{success=true,fileId});}}publicclassUploadModel{publicIFormFileFile{get;set;}publicstringFileId{get;set;}publicintChunkIndex{get;set;}publicintTotalChunks{get;set;}publicstringRelativePath{get;set;}// 文件夹层级路径}
2. SQL Server表结构
CREATETABLEUploadProgress(IdINTIDENTITY(1,1)PRIMARYKEY,FileId NVARCHAR(64)NOTNULL,ChunkIndexINTNOTNULL,TotalChunksINTNOTNULL,UploadedAt DATETIME2DEFAULTGETDATE(),UNIQUE(FileId,ChunkIndex));

断点续传实现

1. 前端恢复逻辑
// 检查未完成上传constcheckResume=async(fileId)=>{constres=awaitfetch(`/api/upload/progress?fileId=${fileId}`);constdata=awaitres.json();if(data.completedChunks<data.totalChunks){uploader.value.option('formData',{fileId,chunk:data.completedChunks});uploader.value.upload();}};// 本地存储fileId(即使浏览器关闭)window.addEventListener('beforeunload',()=>{if(uploader.value.getFiles().length>0){localStorage.setItem('lastUploadId',uploader.value.option('formData').fileId);}});
2. 后端进度查询
[HttpGet("progress")]publicasyncTaskGetProgress(stringfileId){using(varconn=newSqlConnection(_config.GetConnectionString("Default"))){awaitconn.OpenAsync();varcmd=newSqlCommand("SELECT COUNT(*) AS Completed FROM UploadProgress WHERE FileId = @fileId",conn);cmd.Parameters.AddWithValue("@fileId",fileId);varcount=(int)awaitcmd.ExecuteScalarAsync();returnOk(new{completedChunks=count});}}

今日总结

  • 进展:完成文件夹层级解析和.NET Core分片上传逻辑,IE8兼容性方案验证通过。
  • 问题
    1. WebUploader在IE8下对大文件夹性能较差,需优化DOM操作。
    2. SQL Server事务需加强,避免分片记录残留。
  • 明日计划
    1. 实现OSS分片上传(避免本地合并临时文件)。
    2. 编写完整的错误处理和日志系统。

求助:若有熟悉.NET Core文件处理或SQL Server优化的高手,欢迎加入QQ群374992201指导!代码将完全开源回馈社区。


(注:实际项目需补充安全校验、OSS直传和性能监控代码。)

设置框架

安装.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/9/1 7:37:50

5天精通轻量级人脸检测:从原理到落地全攻略

5天精通轻量级人脸检测&#xff1a;从原理到落地全攻略 【免费下载链接】yolov8-face 项目地址: https://gitcode.com/gh_mirrors/yo/yolov8-face 在当今计算机视觉领域&#xff0c;实时人脸检测技术正以前所未有的速度渗透到各行各业。随着边缘计算设备的普及和嵌入式…

作者头像 李华
网站建设 2026/9/3 3:51:49

探索STorM32 BGC:打造专业级影像稳定系统的开源方案

探索STorM32 BGC&#xff1a;打造专业级影像稳定系统的开源方案 【免费下载链接】storm32bgc 3-axis Brushless Gimbal Controller, based on STM32 32-bit microcontroller 项目地址: https://gitcode.com/gh_mirrors/st/storm32bgc 你是否正在寻找一款能够为无人机提…

作者头像 李华
网站建设 2026/9/2 22:33:47

3步攻克魔兽世界技能循环:GSE宏编译器解决方案

3步攻克魔兽世界技能循环&#xff1a;GSE宏编译器解决方案 【免费下载链接】GSE-Advanced-Macro-Compiler GSE is an alternative advanced macro editor and engine for World of Warcraft. It uses Travis for UnitTests, Coveralls to report on test coverage and the Curs…

作者头像 李华
网站建设 2026/9/3 3:52:15

突破网盘下载瓶颈:8大平台直链解析技术指南

突破网盘下载瓶颈&#xff1a;8大平台直链解析技术指南 【免费下载链接】Online-disk-direct-link-download-assistant 可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改&#xff08;改自6.1.4版本&#xff09; &#xff0c;自用&#xff0c;去推广&#xff0c;无需…

作者头像 李华
网站建设 2026/9/2 23:23:52

如何通过MediaCrawler智能采集实现多平台数据获取新方案

如何通过MediaCrawler智能采集实现多平台数据获取新方案 【免费下载链接】MediaCrawler-new 项目地址: https://gitcode.com/GitHub_Trending/me/MediaCrawler-new 在信息爆炸的时代&#xff0c;企业和研究者常常面临这样的困境&#xff1a;如何高效、合规地获取分散在…

作者头像 李华