news 2026/1/22 8:49:53

Vue3如何利用组件实现大文件分块上传的批量处理?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3如何利用组件实现大文件分块上传的批量处理?

【一个被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/1/20 23:16:19

Day 42 图像数据与显存

文章目录 Day 42 图像数据与显存1. 图像数据基础1.1 灰度图像&#xff08;MNIST&#xff09;1.2 彩色图像&#xff08;CIFAR-10&#xff09; 2. 图像相关的神经网络2.1 灰度图像 MLP&#xff08;MNIST&#xff09;2.2 彩色图像 MLP&#xff08;CIFAR-10&#xff09;2.3 batch_…

作者头像 李华
网站建设 2026/1/21 15:41:51

从OneCode看注解革命:Cursor热潮下的国产可视化开源工具新标杆

Cursor 2.0的可视化风暴&#xff0c;让“所见即所得”成为编程效率革命的核心关键词。但在众多可视化工具中&#xff0c;OneCode以“注解驱动双向联动”的独特技术路径脱颖而出——它不只是简单的组件拖拽&#xff0c;更通过标准化注解体系实现了“可视化操作”与“规范代码”的…

作者头像 李华
网站建设 2026/1/22 5:05:00

何时用回溯法?何时用普通 DFS?

要明确「何时用回溯法」「何时用普通 DFS」&#xff0c;核心是抓住目标导向和状态管理两个关键 —— 普通 DFS 侧重「无差别遍历 / 验证」&#xff0c;回溯法侧重「有目的试错找解」。以下是具体判断标准、场景和实例&#xff1a;一、核心判断准则&#xff08;先记这 3 点&…

作者头像 李华
网站建设 2026/1/22 8:29:57

Java 日期时间处理详解

Java 日期时间处理详解 引言 在编程中,对日期和时间的处理是一个非常重要的方面。特别是在Java编程语言中,日期和时间的处理尤为重要,因为它涉及到许多日常应用,如用户信息管理、文件时间戳、数据库操作等。Java提供了丰富的类和工具来处理日期和时间,本文将对Java中的日…

作者头像 李华
网站建设 2026/1/21 7:04:13

测试环境如何生成自签名证书用于 HTTPS

适用场景&#xff1a;本地开发、内网系统、测试环境、Spring Boot、Nginx 在开发或测试阶段&#xff0c;我们经常需要使用 https:// 访问服务&#xff0c;例如&#xff1a; WebRTC&#xff08;浏览器强制要求 HTTPS&#xff09;前端调用受限 API&#xff08;getUserMedia、Ser…

作者头像 李华
网站建设 2026/1/20 19:42:56

20、Linux 输入输出重定向、管道及文件归档操作指南

Linux 输入输出重定向、管道及文件归档操作指南 在 Linux 系统中,高效管理文件和数据是至关重要的。本文将详细介绍 Linux 中输入输出重定向、管道的使用以及文件归档的相关知识,这些技能能够帮助你更好地操作和管理系统中的文件和数据。 输入输出重定向 在 Linux 命令行操…

作者头像 李华