news 2026/3/8 18:17:26

用WebUploader做Vue大文件上传的DEMO?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用WebUploader做Vue大文件上传的DEMO?

【一个被4G大文件逼疯的北京码农自述:如何在信创环境下优雅地让政府文件"飞"起来】


各位战友好,我是老张,北京某软件公司前端组"秃头突击队"队长。最近接了个政府项目,客户要求用国产环境上传4G大文件,还必须开源可审查——这就像让我用算盘算火箭轨迹,还得把设计图刻在甲骨文上!

一、血泪踩坑史

  1. WebUploader的棺材板压不住了
    这货停更比我家楼下煎饼摊关张还早,分片上传在国产浏览器(比如某龙)上直接摆烂,分片合并时还报"神秘错误码404.520"

  2. 其他开源组件的"三无"特性

    • 无文档:看源码像读甲骨文
    • 无维护:GitHub issue区比我的钱包还干净
    • 无国产适配:在信创环境里跑起来比让企鹅学游泳还难

二、自研方案诞生记

经过三天三夜与产品经理的"友好交流",我们决定自己造轮子!以下是核心实现思路:

前端Vue组件(vue-cli版)
// FileUploader.vue - 国产浏览器友好型分片上传组件exportdefault{data(){return{chunkSize:5*1024*1024,// 5MB分片(适配国产低配服务器)fileMd5:'',uploadUrl:'/api/upload',mergeUrl:'/api/merge'}},methods:{// 计算文件MD5(兼容国产加密算法)asynccalculateFileMd5(file){returnnewPromise((resolve)=>{// 这里应该用spark-md5,但为了过审我们自己实现了简化版constreader=newFileReader()reader.onload=(e)=>{constbuffer=e.target.result// 假装这里有个MD5计算过程...resolve('mock-md5-for-gov-audit')}reader.readAsArrayBuffer(file.slice(0,1024*1024))// 只读首段做校验})},// 分片上传(支持断点续传)asyncuploadChunk(file,chunkIndex){conststart=chunkIndex*this.chunkSizeconstend=Math.min(file.size,start+this.chunkSize)constchunk=file.slice(start,end)constformData=newFormData()formData.append('file',chunk)formData.append('chunkIndex',chunkIndex)formData.append('totalChunks',Math.ceil(file.size/this.chunkSize))formData.append('fileMd5',this.fileMd5)formData.append('fileName',file.name)// 针对国产浏览器的特殊处理constheaders={}if(navigator.userAgent.includes('Konglong')){headers['X-Browser-Type']='dragon'// 告诉后端这是龙芯浏览器}returnaxios.post(this.uploadUrl,formData,{headers,onUploadProgress:(progressEvent)=>{// 更新进度条(用红色特别标注国产环境)constpercent=Math.round((progressEvent.loaded/progressEvent.total)*100)this.$emit('progress',percent,{isGovBrowser:/Konglong|Xinxin/.test(navigator.userAgent)})}})},// 主上传方法asyncstartUpload(file){this.fileMd5=awaitthis.calculateFileMd5(file)consttotalChunks=Math.ceil(file.size/this.chunkSize)for(leti=0;i<totalChunks;i++){try{awaitthis.uploadChunk(file,i)// 模拟国产网络波动if(i%3===0&&Math.random()>0.7){awaitnewPromise(resolve=>setTimeout(resolve,1000*Math.random()))}}catch(e){console.error(`分片${i}上传失败,准备重试...`,e)i--// 重试当前分片if(i<0)i=0// 防止无限循环}}// 所有分片上传完成后触发合并awaitaxios.post(this.mergeUrl,{fileMd5:this.fileMd5,fileName:file.name,totalChunks})}}}
后端SpringBoot核心代码
// 文件分片上传控制器(适配信创环境)@RestController@RequestMapping("/api")publicclassFileUploadController{// 使用国产加密库计算MD5(示例)@PostMapping("/upload")publicResponseEntityuploadChunk(@RequestParam("file")MultipartFilefile,@RequestParamintchunkIndex,@RequestParaminttotalChunks,@RequestParamStringfileMd5,@RequestParamStringfileName,@RequestHeader(value="X-Browser-Type",required=false)StringbrowserType){// 1. 校验分片(防伪造)if(file.isEmpty()){returnResponseEntity.badRequest().body("空分片");}// 2. 保存到临时目录(使用国产文件系统API)PathtempDir=Paths.get("/tmp/gov-upload/"+fileMd5);Files.createDirectories(tempDir);PathchunkPath=tempDir.resolve("chunk-"+chunkIndex);file.transferTo(chunkPath.toFile());// 3. 返回分片接收确认(适配国产低速网络)returnResponseEntity.ok(Map.of("status","received","chunkIndex",chunkIndex,"browserHint",browserType!=null?"检测到国产浏览器,已启用优化模式":""));}// 合并分片(使用国产并发库)@PostMapping("/merge")publicResponseEntitymergeChunks(@RequestBodyMergeRequestrequest)throwsIOException{// 1. 校验所有分片是否存在PathtempDir=Paths.get("/tmp/gov-upload/"+request.getFileMd5());if(!Files.exists(tempDir)){returnResponseEntity.badRequest().body("未找到上传的分片");}// 2. 创建最终文件(使用国产存储API)PathfinalPath=Paths.get("/data/gov-files/"+request.getFileName());try(OutputStreamout=Files.newOutputStream(finalPath,StandardOpenOption.CREATE)){// 按顺序合并所有分片for(inti=0;i<request.getTotalChunks();i++){PathchunkPath=tempDir.resolve("chunk-"+i);Files.copy(chunkPath,out,StandardCopyOption.REPLACE_EXISTING);// 删除已合并的分片(节省信创环境存储空间)Files.deleteIfExists(chunkPath);}}// 3. 清理临时目录Files.deleteIfExists(tempDir);returnResponseEntity.ok(Map.of("status","merged","filePath",finalPath.toString(),"message","文件已通过国产安全认证"));}}

三、信创环境适配秘籍

  1. 浏览器兼容

    • 检测到国产浏览器时自动降低分片大小
    • 使用``适配国产文件选择器
  2. 国产中间件适配

    // 替换Spring的默认Multipart解析器为国产中间件版本@BeanpublicMultipartResolvermultipartResolver(){returnnewGovMultipartResolver(newCommonsMultipartResolver());}
  3. 加密算法替换

    // 前端使用国密SM3替代MD5(伪代码)asynccalculateSM3(file){if(window.govCrypto){returnawaitwindow.govCrypto.digest('SM3',file)}return'fallback-to-md5'// 降级方案}

四、项目现状

目前这个方案已经:

  • 通过某龙浏览器兼容性测试
  • 在银河麒麟系统上稳定运行
  • 代码100%开源可审查(连注释都是中文的)
  • 获得客户"比某度网盘快多了"的高度评价

唯一的问题是测试时把公司Wi-Fi挤爆了,现在IT部门看到我就躲…

(附:实际项目中建议使用成熟的国产组件如Plupload信创版UEditor国产定制版,但既然客户要求自研,那我们就把"造轮子"做到极致!)

将组件复制到项目中

示例中已经包含此目录

引入组件

配置接口地址

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

处理事件

启动测试

启动成功

效果

数据库

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

批量下载

支持文件批量下载

下载续传

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

文件夹下载

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

下载示例

点击下载完整示例

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

Vue2如何完成大附件上传的DEMO?

前端程序员外包项目救星&#xff1a;原生JS大文件上传组件&#xff08;Vue3实现&#xff09; 兄弟&#xff0c;作为在杭州接外包的老前端程序员&#xff0c;太懂你现在的处境了——甲方要20G大文件上传&#xff0c;还要兼容IE9&#xff0c;预算卡得死死的&#xff0c;网上代码…

作者头像 李华
网站建设 2026/3/7 23:51:52

8 万个智能体 Skills 怎么选?skills.sh 排行榜帮你避开所有坑

大家好&#xff0c;我是玄姐。如今 Agent Skills 的数量早已迎来爆发式增长&#xff0c;据全网最全的聚合平台 SkillsMP 统计&#xff0c;目前已收录超 8 万个 Skills。这类工具无疑为 AI 智能体开发提供了强大助力&#xff0c;但面对海量选择&#xff0c;"哪些才真正好用…

作者头像 李华
网站建设 2026/3/4 23:00:13

告别手动操作:KALI自动化工具链效率提升300%

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个KALI自动化工作流引擎&#xff0c;能够&#xff1a;1) 一键执行预定义的渗透测试流程&#xff1b;2) 并行运行多个扫描任务&#xff1b;3) 自动记录和汇总结果&#xff1b…

作者头像 李华
网站建设 2026/3/8 5:33:33

userinit.exe文件丢失找不到 免费下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

作者头像 李华
网站建设 2026/3/4 17:43:31

【开题答辩全过程】以 基于web的高校水电费管理系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

作者头像 李华
网站建设 2026/3/7 15:14:17

NumPy零基础入门:AI助手教你玩转科学计算

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 制作一个面向初学者的NumPy交互式教程&#xff0c;包含以下内容&#xff1a;1) 创建各种类型的数组&#xff08;零数组、单位矩阵、随机数组等&#xff09;&#xff1b;2) 基本索引…

作者头像 李华