Node+H5实现大文件分片上传(有源码)

话前

上传大文件上传的教程网上很多, 但是大部分没给出一个比较完整的出来, 这个博客给出的是前后端一套完整的解决方案, 其中前端没有使用第三方上传库, 希望能帮到有同样需求的朋友们.

大文件分片上传的好处在这里就不用多说了, 之前不管是上传单文件还是分片文件上传都是依靠Flash来实现, 现在H5能原生支持, 而且性能要比Flash高很多, 所以正好公司的一个需求就是要分片上传, 借机分享给大家

分片上传的思路如下:

  • 第一步:先对文件进行MD5的加密, 这样有两个好处, 即可以对文件进行唯一的标识, 为秒传做准备, 也可以为后台进行文件完整性的校验进行比对

  • 第二步:拿到MD5值以后, 要查询一下, 这个文件是否已经上传过了, 如果上传过了, 就不用再次重复上传, 也就是能够秒传, 网盘里的秒传, 原理也是一样的

  • 第三步:对文件进行切片, 假如文件是500M, 一个切片大小我们定义为50M, 那么整个文件就为分为100次上传

  • 第四步:向后台请求一个接口, 接口里面的数据是该文件已经上传过的文件块, 为什么要有这个请求呢? 我们经常用网盘, 网盘里面有续传的功能, 一个文件传到一半, 由于各种原因, 不想再传了, 那么再次上传的时候, 服务器应该保留我之前上传过的文件块, 跳过这些已经上传过的块, 再次上传其他文件块, 当然续传方案有很多, 目前来看, 单独发一次请求, 这样效率最高

  • 第五步:开始对未上传过的块进行POST上传

  • 第六步:当上传成功后, 通知服务器进行文件的合并, 至此, 上传完成!

为了直观起见, 我画了一个流程图

图片描述

最终前端的效果图

图片描述

后端的最终文件目录结构

clipboard.png

下面我们说下主要的代码

  • GIF图里的校验文件就是对文件进行MD5+拿这个MD5值, 看下文件是否已经上传

    • 对文件的MD5小文件还好, 大文件的话会比较慢, 经我测试, 4G的文件, MD5的时间大约在2分钟

    • 对文件进行MD5, 我们使用的是spark-md5, 因为这步是浏览器来做, 所以需要引入这个js

    • 因为MD5的大文件时间比较长, 所以要和GIF图一样, 做成带进度的, 这样就需要把文件进行分片的MD5, spark也支持这种方式, 最终的MD5值为spark.end()

    • 和服务器校验文件的ajax请求, 需要传递文件名称和文件的MD5值

    • clipboard.png

    • Node端会处理两件事件, 1.看文件是否存在 2.文件不存在, 返回已上传文件块的list, 文件没上传过, 则list为空

    • clipboard.png

    • 下面我们会对文件进行切片处理(File的API提供slice操作), 序号0-n, (服务器存储的文件形式也是MD5作为文件夹名, 0-n为文件名, 如上面那张服务器结果所示), 然后循环每个分片, 和上面的服务器返回的List做比对, 未在List上的文件进行上传

    • 前端代码:
      clipboard.png

    • node端代码
      clipboard.pngclipboard.png

    • 最后一步, 当所有文件都上传完成, 告知Node端合并文件

    • 前端代码
      clipboard.png

    • Node端代码
      clipboard.png

最后上源码: 点击跳转GitHUb


奥巴驴
干货
2.8k 声望
218 粉丝
0 条评论
推荐阅读
前端集成weex,你需要学习的objective-c基础
最近要把weex集成到App中,需要给iOS和安卓提供库文件,这里的库文件并不是WeexSDK,而是连接iOS和Weex的中间件,所以就接触到oc,如果你也和我一样,需要集成weex,那恭喜你,oc你也需要学习。你可能会有个疑问...

会说话的鱼7阅读 3.1k

ESlint + Stylelint + VSCode自动格式化代码(2023)
安装插件 ESLint,然后 File -> Preference-> Settings(如果装了中文插件包应该是 文件 -> 选项 -> 设置),搜索 eslint,点击 Edit in setting.json

谭光志34阅读 20.7k评论 9

安全地在前后端之间传输数据 - 「3」真的安全吗?
在「2」注册和登录示例中,我们通过非对称加密算法实现了浏览器和 Web 服务器之间的安全传输。看起来一切都很美好,但是危险就在哪里,有些人发现了,有些人嗅到了,更多人却浑然不知。就像是给门上了把好锁,还...

边城32阅读 7.3k评论 5

封面图
涨姿势了,有意思的气泡 Loading 效果
今日,群友提问,如何实现这么一个 Loading 效果:这个确实有点意思,但是这是 CSS 能够完成的?没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们...

chokcoco24阅读 2.2k评论 3

你可能不需要JS!CSS实现一个计时器
CSS现在可不仅仅只是改一个颜色这么简单,还可以做很多交互,比如做一个功能齐全的计时器?样式上并不复杂,主要是几个交互的地方数字时钟的变化开始、暂停操作重置操作如何仅使用 CSS 来实现这样的功能呢?一起...

XboxYan25阅读 1.7k评论 1

封面图
在前端使用 JS 进行分类汇总
最近遇到一些同学在问 JS 中进行数据统计的问题。虽然数据统计一般会在数据库中进行,但是后端遇到需要使用程序来进行统计的情况也非常多。.NET 就为了对内存数据和数据库数据进行统一地数据处理,发明了 LINQ (L...

边城17阅读 2k

封面图
过滤/筛选树节点
又是树,是我跟树杠上了吗?—— 不,是树的问题太多了!🔗 相关文章推荐:使用递归遍历并转换树形数据(以 TypeScript 为例)从列表生成树 (JavaScript/TypeScript) 过滤和筛选是一个意思,都是 filter。对于列表来...

边城18阅读 7.8k评论 3

封面图
2.8k 声望
218 粉丝
宣传栏