放肆青春的博客
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)

放肆青春

一个前端菜鸟的技术成长之路
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)
  • 技术汇总

    • 技术总结
    • 技术文章
  • 技术术语

  • 技术方案

    • 技术场景汇总
    • 技术方案

    • 前端方案

    • 三方平台

    • 图片方案

    • 文件方案

      • 文件上传基础
      • 大文件上传
        • 大文件上传问题汇总
      • 文件下载
  • 技术点

  • 设计模式及原则

    • 设计模式
    • 创建型模式

    • 结构型模式

    • 行为型模式

    • 设计原则
  • technology
放肆青春
2022-01-21

大文件上传

# 大文件上传满足条件

  • 支持拆分上传请求(即切片上传)
  • 支持断点续传
  • 支持显示上传进度和暂停上传

# 大文件上传解决方案

  • vue-simple-uploader 组件

vue-simple-uploader 是基于 simple-uploader.js 封装的 vue 上传插件

安装:npm install vue-simple-uploader --save

教程地址:https://www.cnblogs.com/xiahj/p/vue-simple-uploader.html (opens new window)

# 切片上传

编码方式上传中,在前端我们只要先获取文件的二进制内容,然后对其内容进行拆分,最后将每个切片上传到服务端即可。
在 JavaScript 中,文件 FIle 对象是 Blob 对象的子类,Blob 对象包含一个重要的方法 slice,通过这个方法,我们就可以对二进制文件进行拆分。

实现步骤

  1. 把大文件进行分段(循环分解文件,依次创建文件切片) 比如 2M,发送到服务器携带一个标志,暂时用当前的时间戳,用于标识一个完整的文件

  2. 服务端保存各段文件

  3. 浏览器端所有分片上传完成,发送给服务端一个合并文件的请求

  4. 服务端根据文件标识、类型、各分片顺序进行文件合并

  5. 删除分片文件

切片方案:

  1. 按数量:不管上传文件的大小,切成固定的块数,然后上传。

  2. 按大小:不管上传文件的大小,每次切的块大小相同,然后上传。

第一种方法的缺点就是,如果文件过小的话,切成固定的块数,明显浪费 HTPP 请求,如果文件过大,切成固定的块数,切的每块可能依然过大,即切片的切片还需要继续切片。所以使用这种方法,需要加上限定条件,假如上传文件的大小为 s,限定条件应该这样写 n <= s <= m。

第二种方法的缺点就是,如何确定每次上传文件的大小,定小了,容易出现 HTTP 请求过多,定大了,容易出现切片效果不理想,切片的大小真是让人头疼。

相对优化的方案(两种结合):

  1. 文件过小,不用切片,可以直接上传。例如 10kb、190kb、200kb、甚至 1M……。
  2. 文件三四十兆的这种,就固定切片大小就好。
  3. 大于一百兆但是小于 1G 的这种,可以分区间,不同的区间给不同固定的分包数量。
  4. 如果文件再大,可以两者方法结合用,先固定分包数量,然后随机包大小。
  5. 文件超大的那种,应该寻求并行上传方法,简单点前端可以直接禁止上传超大文件。

# 断点续传

断点续传:可以从已经上传部分开始继续上传未完成的部分,而没有必要从头开始上传,节省上传时间。

解决了大文件上传超时和服务器的限制

实现方案:

  • 为每个切片生成 hash 值,使用 spark-md5 库
  • 在切片上传成功后,保存已上传的切片信息(前端:locaStorage,后端:接口保存,查询)
  • 重新上传时,遍历切片列表,进行和本地分段 hash 值的对比,如果相同的话则跳过,继续下一个分段的上传(只选择未上传的切片进行上传,)
  • 所有切片上传完毕后,再调用 mkfile 接口通知服务端进行文件合并

问题:切片过期

# 秒传

原理:计算整个文件的 HASH,在执行上传操作前,向服务端发送请求,传递 MD5 值,后端进行文件检索。若服务器中已存在该文件,便不进行后续的任何操作,上传也便直接结束。

问题:不想秒传,怎么操作?

要不秒传,其实只要让 MD5 改变,就是对文件本身做一下修改(改名字不行),例如一个文本文件,你多加几个字,MD5 就变了,就不会秒传了.

# 上传进度和暂停

通过 xhr.upload 中的 progress 方法可以实现监控每一个切片上传进度。

上传暂停的实现也比较简单,通过 xhr.abort 可以取消当前未完成上传切片的上传,实现上传暂停的效果,恢复上传就跟断点续传类似,先获取已上传的切片列表,然后重新发送未上传的切片。

# Hash 计算

  1. 秒传,需要通过 MD5 值判断文件是否已存在。

  2. 续传:需要用到 MD5 作为 key 值,当唯一值使用。

# 大文件上传问题汇总

切片上传失败怎么办

上传过程中刷新页面怎么办

如何进行并行上传

切片什么时候按数量切,什么时候按大小切

如何结合 Web Worker 处理大文件上传

如何实现秒传


参考:断点续传和分片上传 (opens new window)

更新时间: 2/15/2022, 7:14:11 PM
文件上传基础
文件下载

← 文件上传基础 文件下载→

最近更新
01
前端权限管理
02-24
02
vue2指令
02-24
03
vue2 hook
02-24
更多文章>
Theme by Vdoing | Copyright © 2019-2022 放肆青春
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式