1、大文件上传文件
简述:web前端开发时我遇到下载大的文件和上传大的文件没有下载视频或者文件就断网或者电脑关机重新开始上传或者下载这个问题的时候 ,我没有思路也不知道如何去处理的时候 搜索了简书、博客、掘金总结如下
- 文件过大会导致带宽资源紧张,请求速度下降 ;
- 如果上传过程中服务中断、网络中断 、页面崩溃,可能会导致文件重新开始上传。
在一篇简书中分析的就很有道理:
- 前端选择文件后上传,后端在处理文件过程中,首先会将文件加载到运行内存中,之后再调用相应的API进行
写入硬盘内存的操作,完成整个文件的上传。
但这样直接上传文件,可能会因为某个环节出了问题导致整个流程崩溃,所以大文件直接上传是不可取的。
解决问题最好办法是分片断点续传,该方式主要是针对大文件(比如100M以上的文件)。
断点?
在文件上传过程中,将一个要上传的文件分成N块,然后使用多线程并发多块上传,因为某种原因导致上传被中断或暂停,此时中断或暂停的位置就成为断点。
前端每上传一片,将会被加载到运行内存中,加载完毕后再写入硬盘,此时运行内存的临时变量会被释放,然后此临时变量会被下一片占用,再进行写入,释放...
续传?
意思是指从中断的位置继续上传剩下的部分文件,而不是从头开始上传。
上传完毕后,在服务端进行合并(合并的操作是在后端进行的,前端只是调用接口,合并的方式是由后端决定的,到底是上传一片就合并一片,或者是上传所有的之后整体进行合并)。
怎么去实现断点续传的实现
1)分片的实现
方式:
html5z之前的方式是flash和activeX
html5提供了文件二进制流进行分割的slice方法。
const chunks = Math.ceil(file.size / eachSize)
文件的分片,一般在2-5M之间。这一步得到了每一片文件的内容、每一块的序号、每一块的大小、总块数等数据。
2)续传的实现
续传首先要确定需要继续上传的是哪一个文件,而确定一个文件的方式是对文件进行加密,只要某个文件内容发生变化,就需要重新上传。可以对文件进行MD5加密作为文件唯一的标识符,MD5加密是不可逆的。
要注意:对整个大文件进行加密,可能会导致页面崩溃,需要对文件进行分片加密。
spark-md5插件支持文件分片加密。
基于elementUI的spark-md5的使用在第一片文件上传之前,需要用文件名称 + 此文件唯一标识符 +当前片数来查询文件是否上传过。通过服务器返回的已经上传的结果,我们可以通过分片的结果获取剩余部分进行上传。如果页面重新加载或者上传中断,只需要在重新上传之前在哪一片中断便可以继续上传。
在上传完毕后,请求合并接口(合并接口也可以不请求,后端拿到所有文件后自己进行合并),在服务端将文件进行合并,此时整个文件上传结束。
在上传过程中,可以根据服务器返回的当前上传成功的片数和总片数对前端进度条进行展示。
(以上内容都是别人的我十分的赞同)后面的我就看不懂了 有待提升!!!
总结方法:
前端通过spark-md5.js计算本地文件md5
这里提供了两个方法;
- 一种是用 SparkMD5.hashBinary( ) 直接将整个文件的二进制码传入直接返回文件的md5、这种方法对于小文件会比较有优势——简单并且速度快。
- 另一种方法是利用js中File对象的 slice( )方法(File.prototype.slice( ))将文件分片后逐个传入spark.appendBinary( ) 方法来计算、最后通过spark.end( )方法输出结果,很明显,这种方法对于大型文件会非常有利——不容易出错,并且能够提供计算的进度信息