背景
最早js是无法处理二进制的,如果非要处理,是通过charCodeAt逐个转化成Unicode编码的二进制数据,知道es5 引入blob,js才算真正可以处理二进制
blob有衍生了一系列如File对象,FileReader对象,FileList对象,URL对象;
Ajax初期只能获取文本数据,在XMLHttpRequest第二个版本也允许了服务器返回二进制数据,如果明确知道返回的二进制数据类型,返回类型就被设置为responseType:arrayBuffer;如果不知道就为blob;
canvas元素输出的二进制元素是TypedArray;
为了配合以上API,es6吧arraybuffer对象,typedarray视图和dataview视图纳入了ecmascript规范,他们都是以数组的语法处理二进制数据,统称二进制数组。
二进制数组并不是真正的数组,而是类似数组的对象。
它很像 C 语言的数组,允许开发者以数组下标的形式,直接操作内存,大大增强了 JavaScript 处理二进制数据的能力,使得开发者有可能通过 JavaScript 与操作系统的原生接口进行二进制通信
二进制数组
arrayBuffer对象
- arrayBuffer表示一段储存了二进制数据的内存
- 不能直接读写arrayBuffer,要用typedarray视图和dataview视图
- 视图的作用是以指定格式解读二进制数据
ArrayBuffer
也是一个构造函数,可以分配一段可以存放数据的连续内存区域。
1 |
|
typedArray视图
- 共包括 9 种类型的视图,比如
Uint8Array
(无符号 8 位整数)数组视图,Int16Array
(16 位整数)数组视图,Float32Array
(32 位浮点数)数组视图等等 TypedArray
视图用来读写简单类型的二进制数据
数据类型 | 字节长度 | 含义 | 对应的 C 语言类型 |
---|---|---|---|
Int8 | 1 | 8 位带符号整数 | signed char |
Uint8 | 1 | 8 位不带符号整数 | unsigned char |
Uint8C | 1 | 8 位不带符号整数(自动过滤溢出) | unsigned char |
Int16 | 2 | 16 位带符号整数 | short |
Uint16 | 2 | 16 位不带符号整数 | unsigned short |
Int32 | 4 | 32 位带符号整数 | int |
Uint32 | 4 | 32 位不带符号的整数 | unsigned int |
Float32 | 4 | 32 位浮点数 | float |
Float64 | 8 | 64 位浮点数 | double |
这 9 个构造函数生成的数组,统称为TypedArray
视图。它们很像普通数组,都有length
属性,都能用方括号运算符([]
)获取单个元素,所有数组的方法,在它们上面都能使用。普通数组与 TypedArray 数组的差异主要在以下方面。
- TypedArray 数组的所有成员,都是同一种类型。
- TypedArray 数组的成员是连续的,不会有空位。
- TypedArray 数组成员的默认值为 0。比如,
new Array(10)
返回一个普通数组,里面没有任何成员,只是 10 个空位;new Uint8Array(10)
返回一个 TypedArray 数组,里面 10 个成员都是 0。 - TypedArray 数组只是一层视图,本身不储存数据,它的数据都储存在底层的
ArrayBuffer
对象之中,要获取底层对象必须使用buffer
属性。
dataView视图
- 可以自定义复合格式的视图,比如第一个字节是 Uint8(无符号 8 位整数)、第二、三个字节是 Int16(16 位整数)、第四个字节开始是 Float32(32 位浮点数)等等,此外还可以自定义字节序。
DataView
视图用来读写复杂类型的二进制数据
DataURL
Data URLs 由四个部分组成:前缀(data:
)、指示数据类型的MIME类型、如果非文本则为可选的base64
标记、数据本身:
1 |
|
mediatype 是个 MIME 类型的字符串,例如 "
image/jpeg" 表示 JPEG 图像文件。如果被省略,则默认值为
text/plain;charset=US-ASCII
如果数据是文本类型,你可以直接将文本嵌入 (根据文档类型,使用合适的实体字符或转义字符)。如果是二进制数据,你可以将数据进行base64编码之后再进行嵌入。
base64
上面提到的 base64 不算是一种加密算法,它只是简单地将每 3 个 8bit 字符转换为 4 个 6Bit 字符(base64 只有 2^6 = 64 种字符,因此得名),这样保证了传输中必定使用 ASCII 中可见字符,不会出奇怪的空白字符或是功能性标志 。
由于是 3 个字符变 4 个,那么很明显了,base64 编码后,编码对象的体积会变成原来的 4/3 倍。
特别要注意的是如果 bit 数不能被 3 整除,需要在末尾添加 1 或 2 个 byte(8 或 16bit),并且末尾的 0 不使用 A 而使用 =,这就是为什么 base64 有的编码结果后面会有一或两个等号。
btoa
WindowOrWorkerGlobalScope.btoa()
从 String
对象中创建一个 base-64 编码的 ASCII 字符串,其中字符串中的每个字符都被视为一个二进制数据字节。
1 |
|
unicode 字符串
在多数浏览器中,使用 btoa()
对 Unicode 字符串进行编码都会触发 InvalidCharacterError
异常。
1 |
|
blob
- 二进制大对象,并非前端特有,计算机通用术语
- 一个Blob对象就是一个包含有只读原始数据的类文件对象
- 一个不可修改的二进制文件
二进制数据关联
概述
- Blob、ArrayBuffer、File可以归为一类,它们都是数据;
- FileReader算是一种工具,用来读取数据;
- FormData可以看做是一个应用数据的场景。
blob和ArrayBuffer
- 相同点: Blob和ArrayBuffer都是二进制的容器;
- ArrayBuffer:ArrayBuffer更底层,就是一段纯粹的内存上的二进制数据,我们可以对其任何一个字节进行单独的修改,也可以根据我们的需要以我们指定的形式读取指定范围的数据
- Blob:Blob就是将一段二进制数据做了一个封装,我们拿到的就是一个整体,可以看到它的整体属性大小、类型;可以对其分割,但不能了解到它的细节
- 联系:Blob可以接受一个ArrayBuffer作为参数生成一个Blob对象,此行为就相当于对ArrayBuffer数据做一个封装,之后就是以整体的形式展现了
- 应用上的区别:由于ArrayBuffer和Blob的特性,Blob作为一个整体文件,适合用于传输;而只有需要关注细节(比如要修改某一段数据时),才需要用到ArrayBuffer
Blob与File
- file是二进制文件,是blob的一个小类,blob的所有属性和方法都可以用于file
数据转化
ArrayBuffer to DataUrl(base64)
- 利用blob作为媒介
- buffer->blob->filereader->dataurl
1 |
|
File/Blob to DataUrl(base64)
- 利用filereader的readAsDataURL
1 |
|
Blob to ArrayBuffer
- 利用filereader的readAsArrayBuffer
1 |
|
ArrayBuffer to Blob
- arraybuffer可以作为New Blob的入参
1 |
|
ArrayBuffer to Uint8
Uint8数组可以直观的看到ArrayBuffer中每个字节(1字节 == 8位)的值。一般我们要将ArrayBuffer转成Uint类型数组后才能对其中的字节进行存取操作。
1 |
|
Uint8 to ArrayBuffer
我们Uint8数组可以直观的看到ArrayBuffer中每个字节(1字节 == 8位)的值。一般我们要将ArrayBuffer转成Uint类型数组后才能对其中的字节进行存取操作。
1 |
|
Array to ArrayBuffer
1 |
|
TypeArray to Array
1 |
|
Blob to File
- 对blob添加name等参数就可以变成file
1 |
|
base64(dataurl) to Blob
1 |
|
string to blob
1 |
|
blob to string
1 |
|
使用场景
生成的blob下载到本地
原理就是利用Blob
对象把需要下载的内容转换为二进制,然后借助``标签的href
属性和download
属性,实现下载。
1 |
|
dataURL图片数据绘制到canvas
- 先构造Image对象,src为dataURL,图片onload之后绘制到canvas
1 |
|
File,Blob的图片文件数据绘制到canvas
- 还是先转换成一个url,然后构造Image对象,src为dataURL,图片onload之后绘制到canvas
- 利用上面的 readBlobAsDataURL 函数,由File,Blob对象得到dataURL格式的url,再参考 dataURL图片数据绘制到canvas
1 |
|
Canvas转换为Blob对象并使用Ajax发送
- 转换为Blob对象后,可以使用Ajax上传图像文件。
- 先从canvas获取dataurl, 再将dataurl转换为Blob对象
1 |
|
总结
- blob作为二进制容器,可以利用fileReader来吧blob文件转化为arrayBuffer,dataurl,string等格式内容,如果要编辑blob文件,可以转化为arraybuffer,通过视图操作然后在转化回来在进行逆向操作
- 基于blob,利用canvas可以实现一系列如图片压缩,图片编辑等前端功能