# LargeFileUpload **Repository Path**: hu_kang/large-file-upload ## Basic Information - **Project Name**: LargeFileUpload - **Description**: 全栈大文件上传案例: 支持文件切片、断点续传、秒传 前端:Vue3 / React 后端: nodejs + express - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2025-12-25 - **Last Updated**: 2025-12-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 大文件上传演示项目 ## 1. 项目概述 ### 1.1 项目名称 大文件上传演示项目(Large File Upload Demo) ### 1.2 技术栈 - **前端技术栈**:Vue 3 + TypeScript + Vite + CryptoJS - **后端技术栈**:Node.js + Express + Multer + Crypto ### 1.3 核心组件 1. **FileUploader**:通用大文件上传组件,支持分片上传、断点续传、秒传等功能 2. **ImageUpload**:图片上传组件,支持单图片上传、预览、压缩等功能 3. **ImageBatchUpload**:批量图片上传组件,支持多图片选择、拖拽上传、批量压缩、批量上传等功能 ### 1.5 项目难点 1. **大文件处理**:如何高效地将大文件分割成多个小分片,并进行并发上传 2. **断点续传**:如何在网络中断或上传失败后,恢复上传进度 3. **秒传**:如何通过文件哈希值快速判断文件是否已存在于服务器 4. **文件完整性**:如何确保上传的文件与原始文件一致 ### 1.4 项目亮点 1. **高效分片上传**:支持将大文件分割成多个小分片,并进行并发上传,提高上传效率 2. **断点续传**:支持在网络中断或上传失败后,恢复上传进度,避免重复上传 3. **秒传**:支持通过文件哈希值快速判断文件是否已存在于服务器,实现快速上传 4. **文件完整性验证**:支持通过SHA-256哈希值验证文件完整性,确保上传的文件与原始文件一致 5. **跨域支持**:支持跨域请求,方便前后端分离部署 ## 2. 项目使用指南 ### 2.1 环境要求 - Node.js 16.x 或更高版本 - npm 或 yarn 包管理器 ### 2.2 安装和运行 #### 2.2.1 后端安装和运行 1. 进入后端目录:`cd backend` 2. 安装依赖:`npm install` 3. 运行后端:`npm start` 4. 后端服务将运行在 `http://localhost:3001` #### 2.2.2 前端安装和运行 1. 进入前端目录:`cd frontend` 2. 安装依赖:`npm install` 3. 运行前端:`npm run dev` 4. 前端服务将运行在 `http://localhost:5173` ### 2.3 组件使用方法 #### 2.3.1 FileUploader(通用大文件上传组件) 1. 打开前端页面:`http://localhost:5173` 2. 在"通用文件上传"卡片中,点击"选择文件"按钮,选择要上传的大文件 3. 点击"上传文件"按钮,开始上传文件 4. 上传过程中可以查看上传进度 5. 上传完成后,会显示文件的访问链接 #### 2.3.2 ImageUpload(图片上传组件) 1. 打开前端页面:`http://localhost:5173` 2. 在"图片上传"卡片中,点击"选择图片"按钮,选择要上传的图片 3. 上传完成后,可以在页面上预览上传的图片 #### 2.3.3 ImageBatchUpload(批量图片上传组件) 1. 打开前端页面:`http://localhost:5173` 2. 在"批量图片上传"卡片中,可以通过以下方式选择图片: - 点击"选择图片"按钮,选择多个要上传的图片 - 将图片拖拽到上传区域 3. 选择图片后,可以在页面上预览所有选中的图片 4. 点击"压缩图片"按钮,可以对所有选中的图片进行批量压缩 5. 点击"上传图片"按钮,开始批量上传图片 6. 上传过程中可以查看每个图片的上传进度 7. 上传完成后,会显示所有上传成功的图片信息 ## 3. 学习指导 ### 3.1 核心组件技术实现 #### 3.1.1 ImageBatchUpload 组件技术实现 **功能特性**: - 多图片选择:支持同时选择多个图片文件 - 拖拽上传:支持将图片拖拽到上传区域 - 图片预览:支持在上传前预览所有选中的图片 - 批量压缩:支持对所有选中的图片进行批量压缩,减小文件大小 - 批量上传:支持同时上传多个图片,提高上传效率 - 进度显示:支持显示每个图片的上传进度 - 错误处理:支持处理上传过程中出现的错误 **技术实现**: 1. **Vue3 Composition API**:使用Vue3的Composition API实现组件逻辑,包括setup函数、ref、reactive、watch等 2. **自定义Hook**:实现了useImageBatchUpload hook,封装了图片处理、压缩、上传等核心功能 3. **图片压缩**:使用canvas API对图片进行压缩,支持设置压缩质量和最大尺寸 4. **拖拽功能**:使用HTML5的拖拽API实现图片拖拽上传功能 5. **响应式设计**:使用CSS Flexbox和Grid实现响应式布局,适配不同屏幕尺寸 **核心接口**: - `CompressionOptions`:压缩选项接口,包括质量、最大宽度、最大高度等 - `UploadOptions`:上传选项接口,包括上传URL、并发数等 - `ImageItem`:图片项接口,包括文件名、大小、类型、预览URL、压缩后的Blob、上传进度等 ### 3.2 大文件上传的全逻辑实现图 ``` ┌───────────────────────────────────────────────────────────────────┐ │ 客户端 │ └───────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ 1. 选择文件 → 计算文件SHA-256哈希值 │ └───────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ 2. 秒传检查 → 向服务器发送文件哈希值,检查文件是否已存在 │ └───────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ 3. 如果文件已存在 → 返回文件访问链接,实现秒传 │ └───────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ 4. 如果文件不存在 → 将文件分割成多个小分片 │ └───────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ 5. 断点续传检查 → 向服务器发送文件名和分片总数,检查已上传分片 │ └───────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ 6. 并发上传分片 → 只上传未完成的分片,支持并发上传和重试 │ └───────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ 7. 合并分片 → 所有分片上传完成后,向服务器发送合并请求 │ └───────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ 8. 验证文件完整性 → 服务器合并分片后,验证文件哈希值是否正确 │ └───────────────────────────────────────────────────────────────────┘ │ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ 9. 返回文件访问链接 → 上传完成,返回文件的访问链接 │ └───────────────────────────────────────────────────────────────────┘ ``` ### 3.2 什么是大文件上传、使用场景,具体的实现步骤? #### 3.2.1 什么是大文件上传? 大文件上传是指将较大的文件(通常大于100MB)上传到服务器的过程。由于大文件上传会占用较多的网络带宽和服务器资源,因此需要采用特殊的技术来优化上传体验。 #### 3.2.2 使用场景 - 视频上传平台:用户上传大型视频文件 - 云存储服务:用户上传大型文档、图片或视频文件 - 企业文件共享:员工上传大型设计文件或数据文件 #### 3.2.3 具体的实现步骤 1. **文件分割**:将大文件分割成多个小分片(通常为几MB到几十MB) 2. **并发上传**:同时上传多个分片,提高上传效率 3. **断点续传**:在网络中断或上传失败后,恢复上传进度,避免重复上传 4. **文件合并**:所有分片上传完成后,将分片合并成原始文件 5. **完整性验证**:验证上传的文件与原始文件是否一致 ### 3.3 什么是秒传,使用场景,具体的实现步骤? #### 3.3.1 什么是秒传? 秒传是指当用户上传的文件已经存在于服务器时,服务器直接返回文件的访问链接,而不需要用户实际上传文件的过程。 #### 3.3.2 使用场景 - 用户重复上传同一文件 - 多个用户上传同一文件 - 文件共享平台,用户上传热门文件 #### 3.3.3 具体的实现步骤 1. **计算文件哈希值**:客户端计算文件的SHA-256哈希值 2. **秒传检查**:客户端向服务器发送文件哈希值,检查文件是否已存在 3. **返回文件访问链接**:如果文件已存在,服务器直接返回文件的访问链接,实现秒传 ### 3.4 什么是断点续传,使用场景,具体的实现步骤? #### 3.4.1 什么是断点续传? 断点续传是指在网络中断或上传失败后,恢复上传进度,而不需要重新上传整个文件的过程。 #### 3.4.2 使用场景 - 网络不稳定,上传过程中容易中断 - 上传大文件,需要较长时间 - 用户需要在不同的设备上继续上传同一文件 #### 3.4.3 具体的实现步骤 1. **文件分割**:将大文件分割成多个小分片 2. **上传前检查**:客户端向服务器发送文件名和分片总数,检查已上传的分片 3. **只上传未完成的分片**:客户端只上传未完成的分片,避免重复上传 4. **上传过程中记录进度**:客户端记录已上传的分片,以便在上传中断后恢复进度 5. **文件合并**:所有分片上传完成后,将分片合并成原始文件 ## 4. 面试指导 ### 4.1 大文件上传在企业开发中的实现 #### 实现思路 大文件上传的核心是**分片处理**,将大文件分割成多个小分片进行并发上传,以提高上传效率和稳定性。 #### 关键性步骤 1. **文件分割**: - 前端使用`File.slice()`方法将大文件分割成固定大小的分片(通常为1MB-10MB) - 为每个分片生成唯一标识(如文件名+分片索引) 2. **并发上传**: - 使用Promise.all或并发控制库(如p-limit)同时上传多个分片 - 控制并发数(通常为3-5个),避免过多并发导致浏览器崩溃或服务器压力过大 3. **文件合并**: - 所有分片上传完成后,前端向服务器发送合并请求 - 服务器根据分片的唯一标识,将所有分片按顺序合并成原始文件 4. **完整性验证**: - 前端计算原始文件的SHA-256哈希值 - 服务器合并文件后,计算合并文件的SHA-256哈希值 - 前后端哈希值比对,确保文件上传完整 ### 4.2 秒传在企业开发中的实现 #### 实现思路 秒传的核心是**文件指纹识别**,通过文件的唯一哈希值快速判断文件是否已存在于服务器。 #### 关键性步骤 1. **计算文件哈希值**: - 前端使用CryptoJS或Web Crypto API计算文件的SHA-256哈希值 - 对于超大文件,可以使用分片计算哈希值的方式,提高计算效率 2. **秒传检查**: - 前端向服务器发送文件哈希值,检查文件是否已存在 - 服务器在数据库中查询该哈希值,如果存在则直接返回文件的访问链接 3. **返回结果**: - 如果文件已存在,服务器返回文件访问链接,实现秒传 - 如果文件不存在,服务器返回不存在的状态,前端开始正常的分片上传 ### 4.3 断点续传在企业开发中的实现 #### 实现思路 断点续传的核心是**进度记录**,记录已上传的分片信息,在上传中断后可以从断点处继续上传。 #### 关键性步骤 1. **记录上传进度**: - 前端在上传过程中,记录已成功上传的分片索引 - 可以将进度信息存储在浏览器的localStorage中,以便在页面刷新后恢复进度 2. **断点检查**: - 在上传开始前,前端向服务器发送文件名和分片总数 - 服务器查询已上传的分片信息,并返回给前端 3. **从断点处继续上传**: - 前端只上传未完成的分片,避免重复上传 - 对于上传失败的分片,可以进行重试,提高上传成功率 4. **完成上传**: - 所有分片上传完成后,前端向服务器发送合并请求 - 服务器合并分片后,验证文件完整性,完成整个上传过程 ### 4.4 给面试官眼前一亮的答案要点 1. **性能优化**: - 分片大小的选择:根据网络状况和文件类型选择合适的分片大小 - 并发数的控制:避免过多并发导致的性能问题 - 哈希值计算优化:对于超大文件,使用分片计算哈希值的方式 2. **用户体验**: - 上传进度显示:实时显示上传进度,让用户了解上传状态 - 重试机制:对于上传失败的分片,自动进行重试 - 断点续传:在网络中断或页面刷新后,从断点处继续上传 3. **安全性**: - 文件完整性验证:使用SHA-256哈希值验证文件完整性 - 权限控制:确保只有授权用户才能上传和访问文件 - 病毒扫描:上传完成后,对文件进行病毒扫描 4. **可扩展性**: - 分布式存储:将文件存储在分布式文件系统中,提高存储容量和性能 - CDN加速:使用CDN加速文件的访问,提高用户体验 - 负载均衡:使用负载均衡器分担服务器的压力,提高系统的稳定性 ``` 随笔记录 /api/upload/chuck index , filename, file 上传单个分片数据(临时文件 : filename.part1) /api/upload/check filename,total (根据total获取临时文件路径, 验证临时文件是否存在, 返回服务器已存在的分片索引) /api/upload/merge filename,total (根据total获取临时文件路径, 异步读取分片数据,将数据写入输出流,删除已写入的分片临时文件, 关闭流并返回文件在服务器的位置) upload: 查询服务器已上传成功的切片索引, 获取未上传的分片,并发上传(开3个异步任务不断上传) 每个异步任务: 每次从未上传的队列头中取出一个切片 调用uploadChunk上传单片 (FormData: file, index, filename,total) 更新已上传分片索引 更新进度条 上传失败可最多重复尝试3次 选择文件: 保存选择的文件 开始上传: uploader = new LargeFileUploader(文件, { chunkSize: 2 * 1024 * 1024, // 2MB 分片(建议2~10mb) concurrent: 3, uploadUrl: 'http://localhost:3001/api/upload/chunk', mergeUrl: 'http://localhost:3001/api/upload/merge' }) uploader.upload(); 文件哈希校验(一致性) ```