ArrayBuffer对象
简介
ArrayBuffer
对象表示一段二进制数据,用来模拟内存里面的数据。通过这个对象,JavaScript 可以读写二进制数据。这个对象可以看作内存数据的表达。
这个对象是 ES6 才写入标准的,普通的网页编程用不到它,为了教程体系的完整,下面只提供一个简略的介绍,详细介绍请看《ES6 标准入门》里面的章节。
浏览器原生提供ArrayBuffer()
构造函数,用来生成实例。它接受一个整数作为参数,表示这段二进制数据占用多少个字节。
var buffer = new ArrayBuffer(8);
上面代码中,实例对象buffer
占用8个字节。
实例属性
byteLength
ArrayBuffer
对象有实例属性byteLength
,表示当前实例占用的内存长度(单位字节)。
var buffer = new ArrayBuffer(8);
buffer.byteLength // 8
实例方法
slice()
ArrayBuffer
对象有实例方法slice()
,用来复制一部分内存。它接受两个整数参数,分别表示复制的开始位置(从0开始)和结束位置(复制时不包括结束位置),如果省略第二个参数,则表示一直复制到结束。
var buf1 = new ArrayBuffer(8);
var buf2 = buf1.slice(0);
上面代码表示复制原来的实例。
Bolb对象
简介
Blob
对象表示一个二进制文件的数据内容,比如一个图片文件的内容就可以通过 Blob
对象读写。它通常用来读写文件,它的名字是 Binary Large Object
(二进制大型对象)的缩写。它与 ArrayBuffer
的区别在于,它用于操作二进制文件,而 ArrayBuffer
用于操作内存。
浏览器原生提供Blob()
构造函数,用来生成实例对象。
new Blob(array [, options])
Blob
构造函数接受两个参数。
- 第一个参数是数组,成员是字符串或二进制对象,表示新生成的
Blob
实例对象的内容; - 第二个参数是可选的,是一个配置对象,目前只有一个属性
type
,它的值是一个字符串,表示数据的 MIME 类型,默认是空字符串。
eg:实例对象myBlob
包含的是字符串。生成实例的时候,数据类型指定为text/html
。
var htmlFragment = ['<a id="a"><b id="b">hey!</b></a>'];
var myBlob = new Blob(htmlFragment, {type : 'text/html'});
eg:Blob 保存 JSON 数据。
var obj = { hello: 'world' };
var blob = new Blob([ JSON.stringify(obj) ], {type : 'application/json'});
实例属性
Blob
具有两个实例属性size
和type
,分别返回数据的大小和类型。
var htmlFragment = ['<a id="a"><b id="b">hey!</b></a>'];
var myBlob = new Blob(htmlFragment, {type : 'text/html'});
myBlob.size // 32
myBlob.type // "text/html"
实例方法
Blob
具有一个实例方法slice
,用来拷贝原来的数据,返回的也是一个Blob
实例。
myBlob.slice(start, end, contentType)
slice
方法有三个参数,都是可选的。它们依次是起始的字节位置(默认为0)、结束的字节位置(默认为size
属性的值,该位置本身将不包含在拷贝的数据之中)、新实例的数据类型(默认为空字符串)。
获取文件信息
文件选择器<input type="file">
用来让用户选取文件。出于安全考虑,浏览器不允许脚本自行设置这个控件的value
属性,即文件必须是用户手动选取的,不能是脚本指定的。一旦用户选好了文件,脚本就可以读取这个文件。
文件选择器返回一个 FileList 对象,该对象是一个类似数组的成员,每个成员都是一个 File 实例对象。File 实例对象是一个特殊的 Blob 实例,增加了name
和lastModifiedDate
属性。
// HTML 代码如下
// <input type="file" accept="image/*" multiple onchange="fileinfo(this.files)"/>
function fileinfo(files) {
for (var i = 0; i < files.length; i++) {
var f = files[i];
console.log(
f.name, // 文件名,不含路径
f.size, // 文件大小,Blob 实例属性
f.type, // 文件类型,Blob 实例属性
f.lastModifiedDate // 文件的最后修改时间
);
}
}
除了文件选择器,拖放 API 的dataTransfer.files
返回的也是一个FileList 对象,它的成员因此也是 File 实例对象。
下载文件
AJAX 请求时,如果指定responseType
属性为blob
,下载下来的就是一个 Blob 对象。
function getBlob(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.onload = function () {
callback(xhr.response);
}
xhr.send(null);
}
上面代码中,xhr.response
拿到的就是一个 Blob 对象。
生成URL
浏览器允许使用URL.createObjectURL()
方法,针对 Blob 对象生成一个临时 URL,以便于某些 API 使用。这个 URL 以blob://
开头,表明对应一个 Blob 对象,协议头后面是一个识别符,用来唯一对应内存里面的 Blob 对象。这一点与data://URL
(URL 包含实际数据)和file://URL
(本地文件系统里面的文件)都不一样。
var droptarget = document.getElementById('droptarget');
droptarget.ondrop = function (e) {
var files = e.dataTransfer.files;
for (var i = 0; i < files.length; i++) {
var type = files[i].type;
if (type.substring(0,6) !== 'image/')
continue;
var 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,产生它们的缩略图,从而使得用户可以预览选择的文件。
上面代码通过为拖放的图片文件生成一个 URL,产生它们的缩略图,从而使得用户可以预览选择的文件。
浏览器处理 Blob URL 就跟普通的 URL 一样,如果 Blob 对象不存在,返回404状态码;如果跨域请求,返回403状态码。Blob URL 只对 GET 请求有效,如果请求成功,返回200状态码。由于 Blob URL 就是普通 URL,因此可以下载。
读取文件
取得 Blob
对象以后,可以通过FileReader
对象,读取 Blob 对象的内容,即文件内容。
FileReader
对象提供四个方法,处理 Blob 对象。Blob 对象作为参数传入这些方法,然后以指定的格式返回。
FileReader.readAsText()
:返回文本,需要指定文本编码,默认为 UTF-8。FileReader.readAsArrayBuffer()
:返回 ArrayBuffer 对象。FileReader.readAsDataURL()
:返回 Data URL。FileReader.readAsBinaryString()
:返回原始的二进制字符串。
eg:下面是FileReader.readAsText()
方法的例子,用来读取文本文件。
// HTML 代码如下
// <input type="file" onchange="readfile(this.files[0])"></input>
// <pre id="output"></pre>
function readfile(f) {
var reader = new FileReader();
reader.readAsText(f);
reader.onload = function () {
var text = reader.result;
var out = document.getElementById('output');
out.innerHTML = '';
out.appendChild(document.createTextNode(text));
}
reader.onerror = function(e) {
console.log('Error', e);
};
}
上面代码中,通过指定 FileReader 实例对象的onload
监听函数,在实例的result
属性上拿到文件内容。
eg:下面是FileReader.readAsArrayBuffer()
方法的例子,用于读取二进制文件。
// HTML 代码如下
// <input type="file" onchange="typefile(this.files[0])"></input>
function typefile(file) {
// 文件开头的四个字节,生成一个 Blob 对象
var slice = file.slice(0, 4);
var reader = new FileReader();
// 读取这四个字节
reader.readAsArrayBuffer(slice);
reader.onload = function (e) {
var buffer = reader.result;
// 将这四个字节的内容,视作一个32位整数
var view = new DataView(buffer);
var 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);
};
}
File对象
简介
File
对象代表一个文件,用来读写文件信息。它继承了 Blob
对象,或者说是一种特殊的 Blob
对象,所有可以使用 Blob
对象的场合都可以使用它。
最常见的使用场合是表单的文件上传控件(<input type="file">
),用户选中文件以后,浏览器就会生成一个数组,里面是每一个用户选中的文件,它们都是 File 实例对象。
// HTML 代码如下
// <input id="fileItem" type="file">
var file = document.getElementById('fileItem').files[0];
file instanceof File // true
上面代码中,file
是用户选中的第一个文件,它是 File 的实例。
构造函数
浏览器原生提供一个File()
构造函数,用来生成 File 实例对象。
new File(array, name [, options])
File()
构造函数接受三个参数。
- array:一个数组,成员可以是二进制对象或字符串,表示文件的内容。
- name:字符串,表示文件名或文件路径。
- options:配置对象,设置实例的属性。该参数可选。
第三个参数配置对象,可以设置两个属性。
type
:字符串,表示实例对象的 MIME 类型,默认值为空字符串。lastModified
:时间戳,表示上次修改的时间,默认为Date.now()
。
下面是一个例子。
var file = new File(
['foo'],
'foo.txt',
{
type: 'text/plain',
}
);
实例属性
File 对象有以下实例属性。
File.lastModified
:最后修改时间File.name
:文件名或文件路径File.size
:文件大小(单位字节)File.type
:文件的 MIME 类型
var myFile = new File([], 'file.bin', {
lastModified: new Date(2018, 1, 1),
});
myFile.lastModified // 1517414400000
myFile.name // "file.bin"
myFile.size // 0
myFile.type // ""
上面代码中,由于myFile
的内容为空,也没有设置 MIME 类型,所以size
属性等于0,type
属性等于空字符串。
实例方法
File 对象没有自己的实例方法,由于继承了 Blob 对象,因此可以使用 Blob 的实例方法slice()
FileList对象
FileList
对象是一个类似数组的对象,代表一组选中的文件,每个成员都是一个 File
实例。它主要出现在两个场合。
- 文件控件节点(
<input type="file">
)的files
属性,返回一个FileList
实例。 - 拖拉一组文件时,目标区的
DataTransfer.files
属性,返回一个FileList
实例。
// HTML 代码如下
// <input id="fileItem" type="file">
var files = document.getElementById('fileItem').files;
files instanceof FileList // true
上面代码中,文件控件的files
属性是一个 FileList 实例。
FileList 的实例属性主要是length
,表示包含多少个文件。
FileList 的实例方法主要是item()
,用来返回指定位置的实例。它接受一个整数作为参数,表示位置的序号(从零开始)。但是,由于 FileList 的实例是一个类似数组的对象,可以直接用方括号运算符,即myFileList[0]
等同于myFileList.item(0)
,所以一般用不到item()
方法。
FileReader对象
FileReader 对象用于读取 File
对象或 Blob
对象所包含的文件内容。
浏览器原生提供一个FileReader
构造函数,用来生成 FileReader
实例。
var reader = new FileReader();
FileReader 有以下的实例属性。
FileReader.error
:读取文件时产生的错误对象FileReader.readyState
:整数,表示读取文件时的当前状态。一共有三种可能的状态,0
表示尚未加载任何数据,1
表示数据正在加载,2
表示加载完成。FileReader.result
:读取完成后的文件内容,有可能是字符串,也可能是一个 ArrayBuffer 实例。FileReader.onabort
:abort
事件(用户终止读取操作)的监听函数。FileReader.onerror
:error
事件(读取错误)的监听函数。FileReader.onload
:load
事件(读取操作完成)的监听函数,通常在这个函数里面使用result
属性,拿到文件内容。FileReader.onloadstart
:loadstart
事件(读取操作开始)的监听函数。FileReader.onloadend
:loadend
事件(读取操作结束)的监听函数。FileReader.onprogress
:progress
事件(读取操作进行中)的监听函数。
下面是监听load
事件的一个例子。
// HTML 代码如下
// <input type="file" onchange="onChange(event)">
function onChange(event) {
var file = event.target.files[0];
var reader = new FileReader();
reader.onload = function (event) {
console.log(event.target.result)
};
reader.readAsText(file);
}
上面代码中,每当文件控件发生变化,就尝试读取第一个文件。如果读取成功(load
事件发生),就打印出文件内容。
FileReader 有以下实例方法。
FileReader.abort()
:终止读取操作,readyState
属性将变成2
。FileReader.readAsArrayBuffer()
:以 ArrayBuffer 的格式读取文件,读取完成后result
属性将返回一个 ArrayBuffer 实例。FileReader.readAsBinaryString()
:读取完成后,result
属性将返回原始的二进制字符串。FileReader.readAsDataURL()
:读取完成后,result
属性将返回一个 Data URL 格式(Base64 编码)的字符串,代表文件内容。对于图片文件,这个字符串可以用于<img>
元素的src
属性。注意,这个字符串不能直接进行 Base64 解码,必须把前缀data:*/*;base64,
从字符串里删除以后,再进行解码。FileReader.readAsText()
:读取完成后,result
属性将返回文件内容的文本字符串。该方法的第一个参数是代表文件的 Blob 实例,第二个参数是可选的,表示文本编码,默认为 UTF-8。
下面是一个例子。
/* HTML 代码如下
<input type="file" onchange="previewFile()">
<img src="" height="200">
*/
function previewFile() {
var preview = document.querySelector('img');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener('load', function () {
preview.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
上面代码中,用户选中图片文件以后,脚本会自动读取文件内容,然后作为一个 Data URL 赋值给<img>
元素的src
属性,从而把图片展示出来。