# big-file-upload **Repository Path**: rockwu_admin/big-file-upload ## Basic Information - **Project Name**: big-file-upload - **Description**: 大文件上传 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-11-20 - **Last Updated**: 2024-08-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # big-file-upload ## 简介 本项目给出了一种用js实现的大文件分片上传的方案。 服务端使用了express,借助spdy实现了http2(主要是为了增加并发请求数量),借用redis存储文件hash值,使用multer中间距处理上传的文件 客户端使用了axios发送请求,p-limit控制并发数量,spark-md5计算文件hash值。为了避免计算hash值占用过多cpu导致渲染进程卡顿,使用了web worker计算hash值。 ## QuickStart ```bash npm i #安装依赖 npm start #启动服务端 npm run dev #启动热编译(前端) npm run build #构建生成环境的文件(前端) ``` ## 整体方案 点击上传按钮以后,整个文件上传过程大致可分为3个阶段: 1. check阶段,浏览器将用户上传的文件分片,并计算文件的hash值和分片hash值,将文件hash值发送给服务端,服务端根据hash值判断文件是否上传,若已经存在,直接返回文件url 2. upload阶段,浏览器将分好片的文件和相应的hash值并行发送给服务端,服务端将文件分片和分片hash存储起来 3. merge阶段,在upload完所有的分片后,浏览器发送一个merge请求,服务端根据文件hash,分片数量,文件名来合并文件,合并完成删除对应分片,并将文件的hash写入redis ps:分片文件命名均以${index}-${wholeFileHash}命名,上传成功后的文件均以${wholeFileHash}.${ext}命名,ext为文件本来的后缀名。 项目的目录结构如下: ```bash ├── README.md ├── babel.config.js ├── ci.yml ├── jest.config.js ├── package-lock.json ├── package.json ├── scripts │ └── build.sh ├── server.crt ├── server.csr ├── server.js 服务端入口,处理路由,redis连接 ├── server.key ├── src │ ├── app.js 客户端入口,处理交互逻辑 │ ├── hash.js 计算hash的web worker │ ├── index.html html模板 │ ├── request.js 封装axios请求 │ └── style.css 样式 ├── stylelint.config.cjs ├── test 测试文件夹 │ ├── getFileExtName.test.js 测试获取文件名后缀 │ ├── mergeFile.test.js 测试文件合并功能 │ └── pipeStream.test.js 测试流传输功能 ├── util.js 服务端的工具函数,包含流传输、文件合并,获取文件名后缀 ├── webpack.config.js └── webpack.dev.js ``` 文件上传的流程如下: ![img](https://rte.weiyun.baidu.com/wiki/attach/image/api/imageDownloadAddress?attachId=433a1b98e727412c8b83519568302ec5&docGuid=WMDxV7hXMVhRpa&sign=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiYXBwSWQiOjEsInVpZCI6IlprMnVFZW5sQWwiLCJkb2NJZCI6IldNRHhWN2hYTVZoUnBhIn0..h5GveHwBZV8JksyW.o4QZZrAuUERqYu5UT6HE-7iyP-OYCgzXegBP1qQJvnfOxUKHnWPFuJSyEs86QX_R0Sd0HwoR0wehnh_gbZMWoed3jdWQyipvP-vaSOaEgMnRKlUiwUTWMXKI-5FwDQD7JH6za8ZQPJH7UPUn4hjohiTKnOeSjHvaTIq4_racV1nUJeUxqV5cQITOn-mfWq581tIFyKZJtTj07bujgRNxwfVyXg.JrMjrQ75IDnyEJIwCc_nIg)