javascript - 有关大文件上传和下载相关知识的整合
做大文件上传和下载,是需要一定的知识储备的。其中综合了不少领域的知识点,很综合的一项技能,可以对技能做一次很好的整合。写一篇这样的文章,也很考验文字水平,希望这一篇文章之后,能够提升自己的理解程度,有一个比较深刻的印象。
说到文件,那肯定少不了前端中的文件(File)、二进制(Blob)、文件读取(FileReader)。大文件上传,一次性上传肯定是不现实的,需要对文件进行分片,然后后端获取后进行整合,那么,Blob.prototype.slice或者File.prototype.slice也是切片时必不可少的。
由于前端会将资源分块,然后单独发送请求,也就是说,原来 1 个文件对应 1 个上传请求,现在可能会变成 1 个文件对应 n 个上传请求(HTTP2的多路复用),所以前端可以基于 Promise.all将这多个接口整合,上传完成在发送一个合并的请求,通知服务端进行合并。合并时可通过 nodejs 中的读写流(readStream/writeStream),将所有切片的流通过管道(pipe)输入
最终文件的流中。
而在发送请求资源时,前端会定好每个文件对应的序号(spark-md5),并将当前分块、序号以及文件 hash 等信息一起发送给服务端(由于计算内容的hash需要时间,还需要考虑 WebWorker),服务端在进行合并时,通过序号进行依次合并即可。
而一旦服务端某个上传请求失败,会返回当前分块失败的信息,其中会包含文件名称、文件 hash、分块大小以及分块序号等,前端拿到这些信息后可以进行重传,同时考虑此时是否需要
将 Promise.all 替换为 Promise.allSettled 更方便。
⑴. Blob:
Blob
对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream
来用于数据操作。
Blob
表示的不一定是 JavaScript
原生格式的数据。File
接口基于 Blob
,继承了 blob
的功能并将其扩展以支持用户系统上的文件。
①要从其它非 blob 对象和数据构造一个 Blob,需使用 Blob() 构造函数:
let blob = new Blob( array, options );
②常用实例属性:
⑵. File:
通常情况下, File
对象是来自用户在一个 <input>
元素上选择文件后返回的 FileList
对象,也可以是来自由拖放操作生成的 DataTransfer
对象,或者来自 HTMLCanvasElement
上的 mozGetAsFile() API
。
File
对象是特殊类型的 Blob
,且可以用在任意的 Blob
类型的 context
中, Blob
的方法都能被File
使用。
①File() 构造器创建新的 File 对象实例。
let myFile = new File(bits, name[, options]);
②常用实例属性:
⑶. FileReader:
FileReader
对象允许 Web
应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File
或 Blob
对象指定要读取的文件或数据。
其中 File
对象可以是来自用户在一个 <input>
元素上选择文件后返回的FileList
对象,也可以来自拖放操作生成的 DataTransfer
对象,还可以是来自在一个 HTMLCanvasElement
上执行 mozGetAsFile()
方法后返回结果。
①使用 FileReader() 构造器去创建一个新的 FileReader。
let reader = new FileReader();
②常用实例属性:
⑷.URL:
版权声明
本文仅代表作者观点,不代表博信信息网立场。