郴州企业网站建设制作,自己做的网页怎么上传网站吗,手机商城网站制作,研究生网站 建设 需求大文件上传系统开发指南#xff08;基于原生JSSpringBoot#xff09;
项目背景
老哥我最近接了个硬骨头项目#xff0c;客户要求实现20G大文件上传下载#xff0c;还要支持文件夹结构保留、加密传输、断点续传#xff0c;还要兼容IE9这种古董浏览器。预算只…大文件上传系统开发指南基于原生JSSpringBoot项目背景老哥我最近接了个硬骨头项目客户要求实现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 }); }); }, } }后端实现SpringBoot1. 文件上传控制器// src/main/java/com/example/uploader/controller/FileUploadController.javapackagecom.example.uploader.controller;RestControllerRequestMapping(/api)publicclassFileUploadController{Value(${file.upload-dir})privateStringuploadDir;// 存储上传进度信息实际项目应该用数据库privatefinalMapprogressMapnewConcurrentHashMap();PostMapping(/upload)publicMaphandleFileUpload(RequestParam(file)MultipartFilefile,RequestParam(relativePath)StringrelativePath,RequestParam(totalChunks)inttotalChunks,RequestParam(currentChunk)intcurrentChunk,RequestParam(fileSize)longfileSize,RequestParam(fileMd5)StringfileMd5,HttpServletRequestrequest)throwsIOException{MapresultnewHashMap();try{// 创建文件存储目录保留文件夹结构PathfilePathPaths.get(uploadDir,relativePath);Files.createDirectories(filePath.getParent());// 如果是加密上传这里应该先解密示例省略// 以追加模式写入文件块try(RandomAccessFilerandomAccessFilenewRandomAccessFile(filePath.toFile(),rw)){randomAccessFile.seek((long)currentChunk*5*1024*1024);// 5MB每块randomAccessFile.write(file.getBytes());}// 更新上传进度UploadProgressprogressprogressMap.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.javaRestControllerRequestMapping(/api)publicclassFileDownloadController{Value(${file.upload-dir})privateStringuploadDir;GetMapping(/download)publicResponseEntitydownloadFile(RequestParamStringrelativePath,HttpServletRequestrequest)throwsIOException{PathfilePathPaths.get(uploadDir,relativePath).normalize();ResourceresourcenewUrlResource(filePath.toUri());if(!resource.exists()){returnResponseEntity.notFound().build();}// 确定内容类型StringcontentTyperequest.getServletContext().getMimeType(resource.getFile().getAbsolutePath());if(contentTypenull){contentTypeapplication/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{privatestaticfinalStringAESAES;// 实际项目应该从安全配置中获取密钥privatestaticfinalbyte[]AES_KEYThisIsASecretKey1234567890.getBytes();// 16/24/32字节publicstaticbyte[]encryptAES(byte[]data)throwsException{SecretKeySpeckeySpecnewSecretKeySpec(AES_KEY,AES);CiphercipherCipher.getInstance(AES);cipher.init(Cipher.ENCRYPT_MODE,keySpec);returncipher.doFinal(data);}}配置文件application.properties# 文件上传目录确保应用有写入权限 file.upload-dir./uploads # Spring Boot默认配置 server.port8080 spring.servlet.multipart.max-file-size10GB spring.servlet.multipart.max-request-size10GB # 数据库配置如果需要 spring.datasource.urljdbc:mysql://localhost:3306/uploader?useSSLfalseserverTimezoneUTC spring.datasource.usernameroot spring.datasource.passwordpassword spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver部署说明环境准备JDK 8MavenNode.js (用于前端开发)MySQL (可选如果需要数据库)构建前端cdfrontendnpminstallnpmrun build构建后端mvn clean package部署将前端构建产物(dist目录)复制到SpringBoot的src/main/resources/static目录运行SpringBoot应用java -jar target/uploader-0.0.1-SNAPSHOT.jarNginx配置可选如果需要处理大文件上传建议使用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不支持FormData和File API的某些特性我们需要做特殊处理前端修改// 在FileUploader.vue中添加IE9兼容代码methods:{handleFileChange(e){constfilese.target.files;if(!files){// IE9兼容处理this.handleIE9FileSelect();return;}// 原有代码...},}后端调整对于IE9的上传请求可能需要使用传统的multipart/form-data方式而非分块上传。加密传输实现如果需要端到端加密可以在前端加密后上传// 在uploadFile方法中添加加密处理asyncuploadFile(fileItem){// ...之前的代码constchunkfile.slice(start,end);letencryptedChunkchunk;// 根据配置选择加密方式if(this.encryptTypeAES){encryptedChunkawaitthis.encryptAES(chunk);}elseif(this.encryptTypeSM4){encryptedChunkawaitthis.encryptSM4(chunk);}constformDatanewFormData();formData.append(file,newBlob([encryptedChunk]));// ...其他参数// ...上传代码},性能优化建议分块大小调整根据网络情况动态调整分块大小5MB-20MB之间并发控制根据用户带宽和设备性能调整并发上传数Web Worker将哈希计算和加密操作放到Web Worker中避免阻塞UI本地缓存使用IndexedDB缓存已计算的哈希值心跳机制定期向服务器发送心跳维护上传会话完整项目结构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的双重限制下。不过通过分块上传、断点续传和合理的架构设计我们还是能够实现客户的需求。关键点总结前端使用原生JS实现核心上传逻辑Vue3负责UI和状态管理后端SpringBoot处理文件存储和进度跟踪分块上传本地缓存实现断点续传保留完整的文件夹结构通过Nginx处理大文件上传实际项目中你可能还需要添加用户认证实现更完善的错误处理和重试机制添加文件预览功能实现更安全的加密方案添加管理员界面希望这个示例能帮到你也欢迎加入我们的QQ群374992201一起交流技术、合作项目。群里定期有技术分享和红包活动还有项目合作机会哦最后提醒一句这种预算的项目记得在合同里明确需求范围和变更条款不然很容易亏本哦导入项目导入到Eclipse点南查看教程导入到IDEA点击查看教程springboot统一配置点击查看教程工程NOSQLNOSQL示例不需要任何配置可以直接访问测试创建数据表选择对应的数据表脚本这里以SQL为例修改数据库连接信息访问页面进行测试文件存储路径up6/upload/年/月/日/guid/filename效果预览文件上传文件刷新续传支持离线保存文件进度在关闭浏览器刷新浏览器后进行不丢失仍然能够继续上传文件夹上传支持上传文件夹并保留层级结构同样支持进度信息离线保存刷新页面关闭页面重启系统不丢失上传进度。下载示例点击下载完整示例