Blob
Blob是一个不可变、原始数据的类文件对象
developer.mozilla.org/zh-CN/docs/…
const blob = new Blob(array, options)
由Blob构造函数可以得到blob实例,其中array为ArrayBuffer, TypedArray, Blob, DOMString。
ArrayBuffer
表示通用的、固定长度的原始二进制数据缓冲区。它是一个字节数组,通常在其他语言中称为“byte array”。
你不能直接操作 ArrayBuffer 的内容,而是要通过类型数组对象(TypedArray)或 DataView 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。
TypedArray
对象描述了一个底层的二进制数据缓冲区(binary data buffer)的一个类数组视图(view)。事实上,没有名为 TypedArray 的全局属性,也没有一个名为 TypedArray 的构造函数
PS: ES 2017中可以 new typedArray()
以下数组的实例都是TypedArray
Int8Array();
Uint8Array();
Uint8ClampedArray();
Int16Array();
Uint16Array();
Int32Array();
Uint32Array();
Float32Array();
Float64Array();
DataView
从 二进制ArrayBuffer 对象中读写多种数值类型的底层接口
关系梳理
图中缺少dataURL(base64)转为blob
TypedArray,Blob(File),DataView,image,Canvas之间可以相互转换。
File与文件上传的两种方式
上传的文件是属于File类型的,可以通过FileReader系列方法将之编程arraybuffer/dataURL/Text。
示例代码
formData文件流
ElementUI中就是使用formData来上传文件的
补充:DataURL ---> Blob
进阶:文件切片上传
file对象是继承blob的,因此可以获取到ArrayBuffer,ArrayBuffer类对象有与普通数组一样的方法,因此通过slice方法截取数组就可以将文件切片(chunk)了。
另外未来识别不同的chunk,需要根据文件内容生成对应的hash值,最后服务端收取所有的hash值后合并
示例代码:下方的代码是基于单个切片串行上传的,因此只需要有一个全局的flag记录断点对应的文件切片即可。对于多个文件并发上传需要进一步优化
Base64上传
除了formData之外,也可以上传base64编码的字符串。
其实本质上就是将file/img转换成DataURL,根据前面的转换图,有以下两种方法
1. 使用FileReader的readAsDataURL方法
2. canvas.toDataURL()方法
补充
TypedArray与普通数组是由差别的:TypedArray不是普通数组,虽然两者有很多相同的方法。TypedArray不继承自Array,Array.isArray(TypedArray)结果是false。
另外,TypedArray的长度是固定的,不会变化,因此可以更改数组长度的方法如shift/pop/splice/push/unshift都不可以使用,此外,concat也不可以使用。
同时,也多了两个可以使用的方法set,subarray
最后
在切片上传中提到了串行上传和并行上传,那么就延伸出了一个问题,如何将上百个切片认为控制并发??
利用递归,代码如下:
模拟网络请求,其请求结果: