【前端知乎系列】ArrayBuffer 和 Blob 对象
本文首发在 个人博客
更多丰富的前端学习资料,可以查看我的 Github: 《Leo-JavaScript》,内容涵盖数据结构与算法、HTTP、Hybrid、面试题、React、Angular、TypeScript和Webpack等等。点个 Star 不迷路~
ArrayBuffer 对象与 Blob 对象大家或许不太陌生,常见于文件上传操作处理(如处理图片上传预览等问题)。
那么本文将与大家深入介绍两者。
一、ArrayBuffer 对象
ArrayBuffer 对象是 ES6 才纳入正式 ECMAScript 规范,是 JavaScript 操作二进制数据的一个接口。ArrayBuffer 对象是以数组的语法处理二进制数据,也称二进制数组。
介绍 ArrayBuffer 对象还需介绍 TypedArray 视图和 DataView 视图,本文不具体介绍,详细可以查看阮一峰老师《ECMAScript 6 入门 ArrayBuffer》 章节。
1. 概念介绍
ArrayBuffer 对象代表储存二进制数据的一段内存,它不能直接读写,只能通过视图(TypedArray视图和DataView视图)来读写,视图的作用是以指定格式解读二进制数据。
关于 TypedArray 视图和 DataView 视图 ,可以查看阮一峰老师《ECMAScript 6 入门 ArrayBuffer》 章节的介绍。
2. 对象使用
浏览器原生提供 ArrayBuffer() 构造函数,用来生成实例。
参数:
- 整数,表示二进制数据占用的字节长度。
返回值:
- 一个指定大小的
ArrayBuffer对象,其内容被初始化为 0。
const buffer = new ArrayBuffer(32);
上面代码表示实例对象 buffer 占用 32 个字节。
3. 实例属性和方法
ArrayBuffer 对象有实例属性 byteLength ,表示当前实例占用的内存字节长度(单位字节),一单创建就不可变更(只读):
const buffer = new ArrayBuffer(32);
buffer.byteLength; //
ArrayBuffer 对象有实例方法 slice(),用来复制一部分内存。
参数如下:
start,整数类型,表示开始复制的位置。默认从 0 开始。
end,整数类型,表示结束复制的位置(不包括结束的位置)。如果省略,则表示复制到结束。
const buffer = new ArrayBuffer(32);
const buffer2 = buffer.slice(0);
4. 兼容性
图片来自 MDN
二、Blob 对象
1. 概念介绍
Blob 全称:Binary Large Object (二进制大型对象)。
Blob 对象表示一个二进制文件的数据内容,通常用来读写文件,比如一个图片文件的内容就可以通过 Blob 对象读写。
与 ArrayBuffer 区别:
Blob用于操作二进制文件ArrayBuffer用于操作内存
2. 对象使用
浏览器原生提供 Blob() 构造函数,用来生成实例。
Blob 的内容由参数数组中给出的值的串联组成。
const leoBlob = new Blob(array [, options]);
参数:
array,必填,成员是字符串或二进制对象,表示新生成的Blob实例对象的内容;
成员可以是一个由 ArrayBuffer , ArrayBufferView , Blob , DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings会被编码为UTF-8。
options,可选,是一个配置对象,这里介绍常用的属性type,表示数据的 MIME 类型,默认空字符串;
options 目前可能有两个属性:type 和 endings。
endings 用于指定包含行结束符 \n 的字符串如何被写入,默认值 transparent。它只有这两个值:native (代表行结束符会被更改为适合宿主操作系统文件系统的换行符)和 transparent (代表会保持blob中保存的结束符不变)。
使用案例:
const leoHtmlFragment = ['<a id="a"><b id="b">hey leo!</b></a>']; // 一个包含 DOMString 的数组
const leoBlob = new Blob(leoHtmlFragment, {type : 'text/html'}); // 得到 blob
该代码中,实例对象 leoBlob 包含的是字符串。生成实例时,指定数据类型为 text/html。
还可以使用 Blob 保存 JSON 数据:
const obj = { hello: 'leo' };
const blob = new Blob([ JSON.stringify(obj) ], {type : 'application/json'});
3. 实例属性和方法
Blob 具有两个实例属性:
size:文件的大小,单位为字节。type:文件的 MIME 类型。如果类型无法确定,则返回空字符串。
const leoHtmlFragment = ['<a id="a"><b id="b">hey leo!</b></a>']; // 一个包含 DOMString 的数组
const leoBlob = new Blob(leoHtmlFragment, {type : 'text/html'}); // 得到 blob leoBlob.size; //
leoBlob.type; // "text/html"
Blob 实例方法:
clice:方法用于创建一个包含源Blob的指定字节范围内的数据的新Blob对象。
const newBlob = oldBlob.slice([start [, end [, contentType]]])
包含三个参数:
start,可选,起始的字节位置,默认 0;
end,可选,结束的字节位置,默认 size 属性的值,不包含该位置;
contentType,可选,新实例的数据类型(默认为空字符串);
4. 兼容性
图片来自 MDN
5. 实际案例
5.1 获取文件信息
文件选择器 <input type="file"> 用来让用户选取文件。出于安全考虑,浏览器不允许脚本自行设置这个控件的 value 属性,即文件必须是用户手动选取的,不能是脚本指定的。一旦用户选好了文件,脚本就可以读取这个文件。
文件选择器返回一个 FileList 对象,该对象是个类数组对象,每个成员都是一个 File 实例对象。File 实例对象是一个特殊的 Blob 实例,增加了 name 和 lastModifiedDate 属性。
也包括拖放 API 的 dataTransfer.files 返回的也是一个 FileList 对象,成员也是 File 实例对象。
// HTML 代码如下
// <input type="file" accept="image/*" multiple onchange="fileinfo(this.files)"/> function fileinfo(files) {
for (let i = 0; i < files.length; i++) {
let f = files[i];
console.log(
f.name, // 文件名,不含路径
f.size, // 文件大小,Blob 实例属性
f.type, // 文件类型,Blob 实例属性
f.lastModifiedDate // 文件的最后修改时间
);
}
}
5.2 下载文件
在 AJAX 请求中,指定 responseType 属性为 blob ,皆可以下下载一个 Blob 对象。
function getBlob(url, callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.onload = function () {
callback(xhr.response);
}
xhr.send(null);
}
然后,xhr.response 拿到的就是一个 Blob 对象。
5.3 生成 URL
浏览器允许使用 URL.createObjectURL() 方法,针对 Blob 对象生成一个临时URL,以便于某些 API 使用。
如作为图片预览的 URL。
这个 URL 以 blob:// 开头,表明对应一个 Blob 对象,协议头后面是一个识别符,用来唯一对应内存里面的 Blob 对象。这一点与 data://URL(URL 包含实际数据)和 file://URL(本地文件系统里面的文件)都不一样。
const droptarget = document.getElementById('droptarget');
droptarget.ondrop = function (e) {
const files = e.dataTransfer.files;
for (let i = 0; i < files.length; i++) {
let type = files[i].type;
if (type.substring(0,6) !== 'image/')
continue;
let img = document.createElement('img');
img.src = URL.createObjectURL(files[i]);
img.onload = function () {
this.width = 100;
document.body.appendChild(this);
URL.revokeObjectURL(this.src);
}
}
}
代码中,通过为拖放的图片文件生成一个 URL,作为预览的缩略图。
浏览器处理 Blob URL 就跟普通的 URL 一样,如果 Blob 对象不存在,返回404状态码;如果跨域请求,返回403状态码。Blob URL 只对 GET 请求有效,如果请求成功,返回200状态码。由于 Blob URL 就是普通 URL,因此可以下载。
5.4 读取文件
取得 Blob 对象以后,可以通过 FileReader 对象,读取 Blob 对象的内容,即文件内容。
FileReader 对象提供四个方法。将 Blob 对象作为参数传入,然后以指定的格式返回。
FileReader.readAsText():返回文本,需要指定文本编码,默认为 UTF-8。FileReader.readAsArrayBuffer():返回 ArrayBuffer 对象。FileReader.readAsDataURL():返回 Data URL。FileReader.readAsBinaryString():返回原始的二进制字符串。
下面是 FileReader.readAsText() 方法的例子,用来读取文本文件:
// HTML 代码如下
// <input type='file' onchange='readfile(this.files[0])'></input>
// <pre id='output'></pre>
function readfile(f) {
let reader = new FileReader();
reader.readAsText(f);
reader.onload = function () {
let text = reader.result;
let out = document.getElementById('output');
out.innerHTML = '';
out.appendChild(document.createTextNode(text));
}
reader.onerror = function(e) {
console.log('Error', e);
};
}
下面是 FileReader.readAsArrayBuffer() 方法的例子,用于读取二进制文件:
// HTML 代码如下
// <input type="file" onchange="typefile(this.files[0])"></input>
function typefile(file) {
// 文件开头的四个字节,生成一个 Blob 对象
let slice = file.slice(0, 4);
let reader = new FileReader();
// 读取这四个字节
reader.readAsArrayBuffer(slice);
reader.onload = function (e) {
let buffer = reader.result;
// 将这四个字节的内容,视作一个32位整数
let view = new DataView(buffer);
let magic = view.getUint32(0, false);
// 根据文件的前四个字节,判断它的类型
switch(magic) {
case 0x89504E47: file.verified_type = 'image/png'; break;
case 0x47494638: file.verified_type = 'image/gif'; break;
case 0x25504446: file.verified_type = 'application/pdf'; break;
case 0x504b0304: file.verified_type = 'application/zip'; break;
}
console.log(file.name, file.verified_type);
};
}
三、参考资料
1. 《ArrayBuffer 对象,Blob 对象》
https://wangdoc.com/javascript/bom/arraybuffer.html
2. 《ECMAScript 6 入门 ArrayBuffer》
https://es6.ruanyifeng.com/#docs/arraybuffe
【前端知乎系列】ArrayBuffer 和 Blob 对象的更多相关文章
- 搞懂前端二进制系列(一):🍇 认识Blob对象
参考资料: https://juejin.cn/post/6844904183661854727 [你不知道的Blob] https://juejin.cn/post/6844904144453517 ...
- 前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输
HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制,故本篇将对其操作对象FileReader进行介绍. FileReader FileReader主要用于将文件内容读入内存,通过一系 ...
- [HTML5] Blob对象
写在前面 本篇主要总结Blob对象属性及作用,通过DEMO介绍Blob对象的应用场景. Blob对象 一直以来,JS都没有比较好的可以直接处理二进制的方法.而Blob的存在,允许我们可以通过JS直接操 ...
- Vue通过Blob对象实现导出Excel功能
不同的项目有不同的导出需求,有些只导出当前所显示结果页面的表格进入excel,这个时候就有很多插件,比如vue-json-excel或者是Blob.js+Export2Excel.js来实现导出Exc ...
- JavaScript 中 Blob对象的初步认识
Blob Binary Large Object的缩写,二进制大对象 虽然在前端中开发并不常见,但是实际上MySql数据库中,可以通过设置一个Blob类型的数据来存储一个Blob对象的内容 语法 le ...
- JS 之Blob 对象类型
原文 http://blog.csdn.net/oscar999/article/details/36373183 什么是Blob? Blob 是什么? 这里说的是一种Javascript的对象类型. ...
- 利用 jQuery-photoClip插件 实现移动端裁剪功能并以Blob对象上传
最近客户要求实现论坛贴子附件裁剪功能,没有考虑js与ios.android容器交互解决方案,单纯用js去实现它的.由于本来附件上传用的别的插件实现的,所以是在此基础上费了不少劲,才把jQuery-ph ...
- HTML5 FileReader读取Blob对象API详解
使用FileReader对象,web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要读取的文件或数据.其中File对象可以是来自用 ...
- mybatis存取blob对象+@Cacheable实现数据缓存
参考文档: http://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/ 需求场景: 当前业务通过第三方接口查询一个业务数据, ...
随机推荐
- PHP laravel+thrift+swoole打造微服务框架
Laravel作为最受欢迎的php web框架一直广受广大互联网公司的喜爱. 笔者也参与过一些由laravel开发的项目.虽然laravel的性能广受诟病但是业界也有一些比较好的解决方案,比如堆机器, ...
- pat 1011 World Cup Betting(20 分)
1011 World Cup Betting(20 分) With the 2010 FIFA World Cup running, football fans the world over were ...
- JQury自动切换图片
[标签]Jquery图片自动切换<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...
- ACE框架 基于共享内存的进程间通讯
ACE框架将基于共享内存的进程间通讯功能,如其它IO组件或IPC组件一样,设计成三个组件.流操作组件ACE_MEM_Stream,连接器组件ACE_MEM_Connector,以及接收连接组件ACE_ ...
- java课笔记
http://127.0.0.1:8088/ http://127.0.0.1:8088/test/index.jsp http://127.0.0.1:8088/test/show 用户 (请求) ...
- 二 linuk系统安装
一 VM虚拟机安装与使用 安装: VM官网:www.vmware.com 不需要太高版本 安装较为简单,选典型安装,别放c盘即可 使用 1.创建虚拟机时,把每个处理器的内核数量调高(我调为8),注意别 ...
- vux组件的样式变量的使用
使用x-header,查看文档发现有个样式变量,可以改变x-header的样式 这玩意怎么用呢? 1.在项目中创建一个.less样式文件,例如我这里是创建一个src/style/vux_theme.l ...
- Java求吸血鬼数算法(通用)
/*吸血鬼数字是指位数为偶数的数字,可以由一 * 对数字相乘而得到,而这对数字各包含乘积的一半位数的数字, * 其中从最初的数字中选取的数字可以任意排序. * 以两个0结尾的数字是不允许的. * * ...
- 使用RNN进行imdb影评情感识别--use RNN to sentiment analysis
原创帖子,转载请说明出处 一.RNN神经网络结构 RNN隐藏层神经元的连接方式和普通神经网路的连接方式有一个非常明显的区别,就是同一层的神经元的输出也成为了这一层神经元的输入.当然同一时刻的输出是不可 ...
- 运用python实现冒泡排序算法
冒泡排序,一个经典的排序算法,因在算法运行中,极值会像水底的气泡一样逐渐冒出来,因此而得名. 冒泡排序的过程是比较两个相邻元素的大小,然后根据大小交换位置,这样从列表左端开始冒泡,最后最大值会依次从右 ...