news 2026/4/1 18:15:29

前端如何通过AJAX实现Java大文件分片上传的并行处理?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
前端如何通过AJAX实现Java大文件分片上传的并行处理?

大文件上传系统开发指南(基于原生JS+SpringBoot)

项目背景

老哥我最近接了个"硬骨头"项目,客户要求实现20G大文件上传下载,还要支持文件夹结构保留、加密传输、断点续传,还要兼容IE9这种古董浏览器。预算只有100块,还要7×24小时技术支持…这活儿简直比相亲还难!

不过没关系,谁让我进了这个"坑"呢?下面我就把这段时间折腾出来的代码和经验分享给大家,希望能帮到同样在"水深火热"中的同行们。

技术选型

  • 前端:Vue3 CLI + 原生JavaScript(客户要求必须用原生JS实现上传核心功能)
  • 后端:SpringBoot + Tomcat
  • 数据库:MySQL(主要存用户信息和文件元数据)
  • 文件存储:直接服务器存储(简单粗暴,符合预算)
  • 加密:SM4(国密)和AES双支持

系统架构

浏览器(IE9+等) ←HTTP/HTTPS→ SpringBoot后端 ←本地文件IO→ 服务器存储 ↑ MySQL

前端实现(Vue3 + 原生JS上传核心)

1. 文件选择组件(支持文件夹)

export default { data() { return { fileList: [], isUploading: false, progress: 0, chunkSize: 5 * 1024 * 1024, // 5MB每片 currentUploads: {} } }, methods: { triggerFileInput() { document.getElementById('fileInput').click(); }, handleFileChange(e) { const files = Array.from(e.target.files); if (files.length === 0) return; // 处理文件夹结构 const fileTree = {}; files.forEach(file => { const path = file.webkitRelativePath || file.name; this.fileList.push({ file: file, relativePath: path, size: file.size, chunks: Math.ceil(file.size / this.chunkSize), uploadedChunks: 0 }); }); }, } }

后端实现(SpringBoot)

1. 文件上传控制器

// src/main/java/com/example/uploader/controller/FileUploadController.javapackagecom.example.uploader.controller;@RestController@RequestMapping("/api")publicclassFileUploadController{@Value("${file.upload-dir}")privateStringuploadDir;// 存储上传进度信息(实际项目应该用数据库)privatefinalMapprogressMap=newConcurrentHashMap<>();@PostMapping("/upload")publicMaphandleFileUpload(@RequestParam("file")MultipartFilefile,@RequestParam("relativePath")StringrelativePath,@RequestParam("totalChunks")inttotalChunks,@RequestParam("currentChunk")intcurrentChunk,@RequestParam("fileSize")longfileSize,@RequestParam("fileMd5")StringfileMd5,HttpServletRequestrequest)throwsIOException{Mapresult=newHashMap<>();try{// 创建文件存储目录(保留文件夹结构)PathfilePath=Paths.get(uploadDir,relativePath);Files.createDirectories(filePath.getParent());// 如果是加密上传,这里应该先解密(示例省略)// 以追加模式写入文件块try(RandomAccessFilerandomAccessFile=newRandomAccessFile(filePath.toFile(),"rw")){randomAccessFile.seek((long)currentChunk*5*1024*1024);// 5MB每块randomAccessFile.write(file.getBytes());}// 更新上传进度UploadProgressprogress=progressMap.computeIfAbsent(fileMd5,k->newUploadProgress(fileMd5,relativePath,fileSize,totalChunks));progress.markChunkUploaded(currentChunk);// 如果是最后一块,清理进度信息if(progress.isComplete()){progressMap.remove(fileMd5);// 这里可以触发文件后处理,如加密存储等}result.put("success",true);result.put("message","Chunk uploaded successfully");result.put("uploadedChunks",progress.getUploadedChunks());}catch(Exceptione){result.put("success",false);result.put("message","Upload failed: "+e.getMessage());}returnresult;}}

2. 文件下载控制器

// src/main/java/com/example/uploader/controller/FileDownloadController.java@RestController@RequestMapping("/api")publicclassFileDownloadController{@Value("${file.upload-dir}")privateStringuploadDir;@GetMapping("/download")publicResponseEntitydownloadFile(@RequestParamStringrelativePath,HttpServletRequestrequest)throwsIOException{PathfilePath=Paths.get(uploadDir,relativePath).normalize();Resourceresource=newUrlResource(filePath.toUri());if(!resource.exists()){returnResponseEntity.notFound().build();}// 确定内容类型StringcontentType=request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());if(contentType==null){contentType="application/octet-stream";}returnResponseEntity.ok().contentType(MediaType.parseMediaType(contentType)).header(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=\""+filePath.getFileName()+"\"").body(resource);}}

3. 加密工具类(简化版)

// src/main/java/com/example/uploader/util/CryptoUtil.javapackagecom.example.uploader.util;importjavax.crypto.Cipher;importjavax.crypto.spec.SecretKeySpec;importjava.util.Base64;publicclassCryptoUtil{privatestaticfinalStringAES="AES";// 实际项目应该从安全配置中获取密钥privatestaticfinalbyte[]AES_KEY="ThisIsASecretKey1234567890".getBytes();// 16/24/32字节publicstaticbyte[]encryptAES(byte[]data)throwsException{SecretKeySpeckeySpec=newSecretKeySpec(AES_KEY,AES);Ciphercipher=Cipher.getInstance(AES);cipher.init(Cipher.ENCRYPT_MODE,keySpec);returncipher.doFinal(data);}}

配置文件

application.properties

# 文件上传目录(确保应用有写入权限) file.upload-dir=./uploads # Spring Boot默认配置 server.port=8080 spring.servlet.multipart.max-file-size=10GB spring.servlet.multipart.max-request-size=10GB # 数据库配置(如果需要) spring.datasource.url=jdbc:mysql://localhost:3306/uploader?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

部署说明

  1. 环境准备

    • JDK 8+
    • Maven
    • Node.js (用于前端开发)
    • MySQL (可选,如果需要数据库)
  2. 构建前端

    cdfrontendnpminstallnpmrun build
  3. 构建后端

    mvn clean package
  4. 部署

    • 将前端构建产物(dist目录)复制到SpringBoot的src/main/resources/static目录
    • 运行SpringBoot应用:
      java -jar target/uploader-0.0.1-SNAPSHOT.jar
  5. Nginx配置(可选)
    如果需要处理大文件上传,建议使用Nginx反向代理:

    server { listen 80; server_name yourdomain.com; client_max_body_size 21G; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

兼容性处理

IE9兼容性方案

由于IE9不支持FormDataFile API的某些特性,我们需要做特殊处理:

  1. 前端修改
// 在FileUploader.vue中添加IE9兼容代码methods:{handleFileChange(e){constfiles=e.target.files;if(!files){// IE9兼容处理this.handleIE9FileSelect();return;}// 原有代码...},}
  1. 后端调整

对于IE9的上传请求,可能需要使用传统的multipart/form-data方式而非分块上传。

加密传输实现

如果需要端到端加密,可以在前端加密后上传:

// 在uploadFile方法中添加加密处理asyncuploadFile(fileItem){// ...之前的代码constchunk=file.slice(start,end);letencryptedChunk=chunk;// 根据配置选择加密方式if(this.encryptType==='AES'){encryptedChunk=awaitthis.encryptAES(chunk);}elseif(this.encryptType==='SM4'){encryptedChunk=awaitthis.encryptSM4(chunk);}constformData=newFormData();formData.append('file',newBlob([encryptedChunk]));// ...其他参数// ...上传代码},

性能优化建议

  1. 分块大小调整:根据网络情况动态调整分块大小(5MB-20MB之间)
  2. 并发控制:根据用户带宽和设备性能调整并发上传数
  3. Web Worker:将哈希计算和加密操作放到Web Worker中,避免阻塞UI
  4. 本地缓存:使用IndexedDB缓存已计算的哈希值
  5. 心跳机制:定期向服务器发送心跳,维护上传会话

完整项目结构

file-uploader/ ├── frontend/ # Vue3前端 │ ├── src/ │ │ ├── components/ │ │ │ └── FileUploader.vue │ │ ├── App.vue │ │ └── main.js │ ├── package.json │ └── vue.config.js ├── backend/ # SpringBoot后端 │ ├── src/ │ │ ├── main/ │ │ │ ├── java/com/example/uploader/ │ │ │ │ ├── controller/ │ │ │ │ ├── util/ │ │ │ │ └── Application.java │ │ │ └── resources/ │ │ │ └── application.properties │ └── pom.xml ├── uploads/ # 文件存储目录(自动创建) ├── nginx.conf # Nginx配置示例 └── README.md # 项目说明

总结

这个项目确实是个挑战,特别是在100元预算和兼容IE9的双重限制下。不过通过分块上传、断点续传和合理的架构设计,我们还是能够实现客户的需求。

关键点总结:

  1. 前端使用原生JS实现核心上传逻辑,Vue3负责UI和状态管理
  2. 后端SpringBoot处理文件存储和进度跟踪
  3. 分块上传+本地缓存实现断点续传
  4. 保留完整的文件夹结构
  5. 通过Nginx处理大文件上传

实际项目中,你可能还需要:

  • 添加用户认证
  • 实现更完善的错误处理和重试机制
  • 添加文件预览功能
  • 实现更安全的加密方案
  • 添加管理员界面

希望这个示例能帮到你,也欢迎加入我们的QQ群(374992201)一起交流技术、合作项目。群里定期有技术分享和红包活动,还有项目合作机会哦!

最后提醒一句:这种预算的项目,记得在合同里明确需求范围和变更条款,不然很容易亏本哦!

导入项目

导入到Eclipse:点南查看教程
导入到IDEA:点击查看教程
springboot统一配置:点击查看教程

工程

NOSQL

NOSQL示例不需要任何配置,可以直接访问测试

创建数据表

选择对应的数据表脚本,这里以SQL为例

修改数据库连接信息

访问页面进行测试

文件存储路径

up6/upload/年/月/日/guid/filename

效果预览

文件上传

文件刷新续传

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

文件夹上传

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

下载示例

点击下载完整示例

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

vue基于python的中学学生成绩查询_n8roe74c(pycharm django flask)

目录已开发项目效果实现截图开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;已开发项目效果实现截图 同行可拿货,招校园代理 vue基于python的中学学生成绩查询_n8roe74c(pycharm django f…

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

为什么90%的开发者卡在Open-AutoGLM第一步?深度剖析安装流程中的隐藏陷阱

第一章&#xff1a;Open-AutoGLM安装全景概览Open-AutoGLM 是一个面向自动化代码生成与自然语言任务处理的开源框架&#xff0c;支持多种编程语言集成和模型热插拔机制。其模块化设计允许开发者快速部署本地服务或接入云端推理引擎。环境准备 在开始安装前&#xff0c;请确保系…

作者头像 李华
网站建设 2026/3/30 23:40:18

大模型选型难题(Open-AutoGLM vs ChatGLM 究竟有何不同)

第一章&#xff1a;大模型选型难题的背景与意义 在人工智能技术迅猛发展的今天&#xff0c;大规模预训练模型已成为推动自然语言处理、计算机视觉和多模态任务进步的核心驱动力。然而&#xff0c;随着模型参数量的不断攀升&#xff0c;如何从众多候选模型中选择最适合特定业务场…

作者头像 李华
网站建设 2026/4/1 5:03:16

Open-AutoGLM难用?切换这4款高口碑App,开发效率立升300%

第一章&#xff1a;Open-AutoGLM类似的app哪个好用在探索自动化语言模型应用的过程中&#xff0c;Open-AutoGLM 提供了强大的本地化推理与任务自动化能力。然而&#xff0c;对于希望寻找替代方案的用户&#xff0c;市面上已有多个功能相似且体验更优的应用可供选择。主流替代应…

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

Open-AutoGLM和ChatGLM究竟谁更强?:从架构到落地的全面剖析

第一章&#xff1a;Open-AutoGLM沉思和ChatGLM的宏观定位在大模型技术迅猛发展的背景下&#xff0c;ChatGLM系列模型凭借其高效的中英双语理解能力与本地化部署优势&#xff0c;已成为企业级AI应用的重要基石。而Open-AutoGLM作为其自动化推理扩展框架&#xff0c;致力于将复杂…

作者头像 李华
网站建设 2026/3/29 12:04:48

Open-AutoGLM卡顿崩溃频发?紧急推荐5款稳定高效的同类工具(速看)

第一章&#xff1a;Open-AutoGLM卡顿崩溃问题深度解析在部署和使用 Open-AutoGLM 模型过程中&#xff0c;部分用户频繁反馈系统出现卡顿甚至进程崩溃的现象。此类问题多集中于高并发推理、长文本生成及显存资源紧张的场景&#xff0c;严重影响实际应用体验。深入分析表明&#…

作者头像 李华