这是一个分片上传的 DEMO ,包含前后端,后端使用 node.js 。
npm i
// 用一个终端来打开前端部分
npm start
// 用另一个终端来打开server
npm run server
- 在浏览器里打开
http://localhost:3000
页面。 - 如果要测试多终端上传,则多开浏览器窗口。
- 上传文件。
- 文件唯一标识,每个文件都用 Web Worker 开个线程来计算文件内容的 hash ,这个 hash 就是文件的唯一标识。
- 分片:从上传框的 DOM 元素里拿到 File 对象,多次调用 File 对象的
slice([start [, end]])
方法,就可以把文件切成多个文件分片;为了后端能够合并文件分片,还需要把文件分片的序号告知后端。 - 断点续传/秒传:上传前先根据文件唯一标识向后端请求,查询文件的上传情况,如果文件已经上传完成的,那么就返回文件信息;如果文件是部分上传的,就返回已上传的分片的序号,前端这边就可以继续上传那些还没上传的分片。
- 多终端上传:支持多终端同时上传同一文件。
- 接到前端上传前的请求后,在本地文件数据库(node-json-db)里以文件的 hash 来搜索,搜到的话就返回给前端;如果没有搜到的话,就根据请求中附带的参数,包括文件 hash、有多少个分片等等信息,在本地文件数据库建立一个初始的数据结构(map)。
- 这个数据结构有一个内容是比较重要的,那就是所有分片的上传状态;前端可以根据这个信息来决定上传哪些分片。
- 另外,如果有另外一台机器正在上传同一个文件,我们需要在正式上传某个文件分片时,前端先发请求修改该文件分片的上传状态为“上传中”,在这个过程中如果发现该文件分片的状态不是“未上传”,那就舍弃掉。
- 等到所有文件分片上传完毕的时候,前端会发起合并文件的请求,后端就根据文件分片的顺序建立文件可读流(
fs.createReadStream()
),然后通过管道输出到新文件的可写流上(fs.createWriteStream()
)。
- 多文件上传
- 并发上传
- 进度条
- 暂停/恢复上传
- 低版本浏览器兼容
- 异常情况处理:某个后端接口报错,如
500
等 - 异常情况处理:在多终端中,某终端在上传某个分片时异常退出,其它终端需要补上传该终端未上传完成的分片