This article first appeared in the personal blog
More rich front-end learning materials, you can view my Github: " Leo-JavaScript ", covering data structures and algorithms, HTTP, Hybrid, face questions, React, Angular, the typescript and Webpack and so on.Star - a point not lost
ArrayBuffer
Subjects and Blob
objects we perhaps less familiar, common in the file upload operation processing (such as processing image upload preview and so on).
Then this article will work with our in-depth description of both.
A, ArrayBuffer objects
ArrayBuffer
The object is ES6 was officially incorporated into the ECMAScript specification is a JavaScript interface to operate the binary data. ArrayBuffer
The syntax objects are working with binary data arrays, also known as a binary array.
Introduction ArrayBuffer
objects need to introduce TypedArray
view and the DataView
view, this article does not introduce specific details can be viewed Ruan Yifeng teacher "ECMAScript 6 Getting ArrayBuffer" section.
1. Concepts
ArrayBuffer
Object represents a section of memory to store binary data, it can not directly read and write only through the view ( TypedArray
the view and DataView
to write view), the role is a view interpret the binary data in the specified format.
About TypedArray
view and the DataView
view, you can see Ruan Yifeng teacher "ECMAScript 6 Getting ArrayBuffer" Introduction chapter.
2. Use objects
Native browser provided ArrayBuffer()
constructor to generate instances.
parameter:
-
An integer indicating the byte length occupied by the binary data.
return value:
-
A size designated
ArrayBuffer
object whose contents are initialized to zero.
const buffer = new ArrayBuffer(32);
The above code shows an example of an object buffer
occupies 32 bytes.
3. Examples of properties and methods
ArrayBuffer
The object has an instance property byteLength
, represents the current instance of the memory byte length (in bytes), it can not create a single change (read only):
const buffer = new ArrayBuffer(32);buffer.byteLength; // 32
ArrayBuffer
Examples of object has a method slice()
for copying a portion of the memory.
Parameters are as follows:
-
start, integer type, indicates the position to start copying. The default start from zero.
-
End, integer type, indicates the position of the end of replication (not including the end position). If omitted, then copy to the end.
const buffer = new ArrayBuffer(32);const buffer2 = buffer.slice(0);
4. Compatibility
Pictures from MDN
Two, Blob objects
1. Concepts
Blob
Full Name: Binary Large Object
(binary large objects).
Blob
Object represents the contents of a binary data file, usually used to read and write files, such as the contents of a picture file can pass Blob
objects to read and write.
And ArrayBuffer
the difference between:
-
Blob
For operating a binary file -
ArrayBuffer
For operating memory
2. Use objects
Native browser provided Blob()
constructor to generate instances.
Blob
Series of values given by the contents of the composition parameters of the array.
const leoBlob = new Blob(array [, options]);
parameter:
-
array
, Required members of a string or binary object that represents the content of the new generation of Blob instance of an object;
成员可以是一个由 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'}); // 得到 blobleoBlob.size; // 38leoBlob.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