背景
Blob 对象是 二进制大型对象( binary large object )的简称,顾名思义用来表示二进制数据内容。Blob 对象数据可以按文本或二进制格式进行读取,而且是不可变的。
数据可以来源于文件,因此 Blob 可以用来读写文件,比如读写一个图片文件的内容。操作文件通常采用 File 对象,File 继承了 Blob 的数据读写功能,并在此基础上扩展实现文件系统相关功能。
本文先讲解 Blob 对象相关接口,再讲解一些典型应用场景,最终彻底掌握 Blob 对象用法。
接口
构造函数
浏览器原生提供 Blob() 构造函数,用来创建 Blob 对象实例,接口如下:
|
|
- blobParts 参数必填,它是一个由字符串或二进制对象组成的数组;
- options 参数是可选的,它是一个配置对象,传递一些额外的属性,比如 type ,表示数据的 MIME 类型;
举个例子,fragments 数组保存一些 HTML 片段,创建一个 Blob 对象将它们串联起来:
|
|
这就是 Blob 对象通过数组指定数据内容的好处,就算数据由若干片段串联而成,也无须手工拼接。
下面这个例子创建一个 Blob 对象,保存 data 对象的 JSON 序列化数据:
|
|
属性
- Blob.size ,所包含数据的大小,只读;
- Blob.type ,表示数据 MIME 类型的字符串,类型未知则为空字符串,只读;
方法
- Blob.slice([start[, end[, contentType]]]) ,返回包含指定范围数据的新 Blob 对象;
- Blob.stream() ,返回一个能够读取 Blob 数据内容的 ReadableStream ;
- Blob.text() ,返回 Promise ,获得包含 Blob 所有数据的 UTF-8 格式 USVString ;
- Blob.arrayBuffer() ,返回 Promise ,获得包含 Blob 所有数据的二进制格式 ArrayBuffer ;
File对象
文件操作是 Blob 对象的典型使用场景,为此 JS 提供了 File 对象。它拥有 Blob 对象的全部功能,但增加了 name 和 lastModifiedDate 等文件相关属性。我们来看一个例子:
See the Pen for-var by fasionchan (@fasionchan) on CodePen.
浏览器提供的 input 文件选择器可供用户选择文件,用户选好后浏览器会执行 onchange 属性指定的代码。通过 this.files 可以取得用户选好的文件,这是一个 File 对象数组。
在上述例子中选择一个文件,即可在 console 中看到 File 对象结构大致如下:
|
|
有了 File 对象,我们就在 JS 中操作用户选择的文件,比如读取文件内容并上传。
AJAX
在 AJAX 请求中,如果指定 responseType 属性为 blob ,便可以将请求响应的数据,以 Blob 对象的形式返回。我们来看一个简单的例子:
See the Pen for-var by fasionchan (@fasionchan) on CodePen.
这段代码通过 AJAX 请求数据,通过 responseType 属性指定返回 Blob 对象:
|
|
Blob 对象表明服务器返回的是 JSON 数据,总共 4306 字节,调用 Blob 对象即可读取这些数据。
应用场景
URL生成
图片预览场景通常需要先在网页上展示用户选择的图片,效果没问题后再上传。可问题是:图片还没上传,哪来的 URL 呢?img 标签如何显示图片呢?
好在浏览器允许使用 URL.createObjectURL() 方法,为 Blob 对象生成一个临时的 URL ,这样就可以通过 URL 访问 Blob 对象中的数据。这在需要通过 URL 访问 Blob 数据的场景中非常有用,img 图片就是一个典型的例子。
这个例子演示了如何调用 URL.createObjectURL() 为 Blob 对象生成 URL 以实现图片预览:
See the Pen for-var by fasionchan (@fasionchan) on CodePen.
请看代码,用户选择图片后,浏览器将调用 imagesSeleted 函数,并将 File 对象数组传进来:
- 先检查数据长度并取出代表用户选定图片的 File 对象;
- 调用 URL.createObjectURL() 方法为 File 对象生成 URL ( File 对象也是一种 Blob 对象);
- 创建 img 标签,并实现 onload 回调函数,在图片加载完毕后将图片插入网页,并销毁图片的临时 URL ;
- 设置 img 标签 src 属性指向图片的临时 URL ,加载完毕后执行 onload 回调函数;
您可随意选择一张图片,观察 console 中的输出。可以看到 URL 以 blob://
开头,表明这对应一个 Blob 对象。URL 中包含一个唯一标识符,用来唯一确定内存中的 Blob 对象。
浏览器处理 Blob URL 跟普通 URL 一样,请求成功,返回状态码 200 ,也支持下载。如果 Blob 对象不存在,则返回状态码 404 。
文件下载
Blob 对象支持生成 URL ,这意味着我们可以将内存中的数据以文件的形式下载下来。这个例子用 JS 生成了一份 JSON 数据,并通过 a 标签触发下载:
See the Pen for-var by fasionchan (@fasionchan) on CodePen.
这段代码先构造一个 Blob 对象,内容是 plain/text 文本。然后调用 downloadBlob 函数将其下载为文件,该函数先为 Blob 对象生成一个 URL ,再创建一个 a 标签触发下载。
通过 a 标签动态触发文件下载,其实跟 Blob 对象关系不大,理论上任何 URL 都可以通过这种方式触发下载。Blob 对象支持生成 URL ,因此支持下载为文件,这个用法很常见。
文件上传
有时我们需要将内存中的数据,以文件的方式上传到服务器。这时可以将数据转成 Blob 对象,因为 Blob 对象可作为文件放在表单中提交:
|
|
这段代码将 Blob 对象作为文件添加到表单,append 方法第一个参数是字段名,服务端通过它来取文件;第二个参数是要上传的 Blob 对象;第三个参数是文件名,告诉服务端文件原名是什么。
当然了,我们也可以将 Blob 数据进一步包装成 File 对象来上传,不过兼容性稍差一些:
|
|
用 File 对象上传跟用 Blob 对象类似,只不过 File 对象可以保存文件名,因而不用传给 append 。
数据读取
想要读取 Blob 对象中的数据,可以创建一个 FileReader 对象,然后调用 readAsText 方法即可:
See the Pen for-var by fasionchan (@fasionchan) on CodePen.
请看代码,当用户选好文件后,将执行 readBlob 函数读取内容。只要是 Blob 对象,都可以通过这种方式读取。由于 File 对象也是 Blob 对象中的一种,因此 readBlob 也能处理。
全部源码
文件选择器返回File对象
|
|
AJAX请求返回Blob对象
|
|
为Blob对象生成URL
|
|
下载Blob对象
|
|
读取Blob对象数据
|
|
订阅更新,获取更多学习资料,请关注我们的公众号: