ArrayBuffer

ArrayBuffer是浏览器原生提供的对象,同时也是一个构造函数。

ArrayBuffer 对象表示一段二进制数据,用来模拟内存里面的数据。通过这个对象,JavaScript 可以读写二进制数据。这个对象可以看作内存数据的表达。

这个对象是 ES6 才写入标准的,普通的网页编程用不到它,为了教程体系的完整,下面只提供一个简略的介绍,详细介绍请看《ES6 标准入门》里面的章节。

浏览器原生提供ArrayBuffer()构造函数,用来生成实例。它接受一个整数作为参数,表示这段二进制数据占用多少个字节。

  1. var buffer = new ArrayBuffer(8);
  2. //实例对象buffer占用8个字节。

ArrayBuffer 对象有实例属性byteLength,表示当前实例占用的内存长度(单位字节)。

  1. var buffer = new ArrayBuffer(8);
  2. buffer.byteLength // 8

Blob 对象

Blob是浏览器原生提供的对象,同时也是一个构造函数。

Blob 对象表示一个二进制文件的数据内容,比如一个图片文件的内容就可以通过 Blob 对象读写。它通常用来读写文件,它的名字是 Binary Large Object (二进制大型对象)的缩写。它与 ArrayBuffer 的区别在于,它用于操作二进制文件,而 ArrayBuffer 用于操作内存。

构造函数

语法:

  1. new Blob(array [, options])

Blob构造函数接受两个参数。第一个参数是数组,成员是字符串或二进制对象,表示新生成的Blob实例对象的内容;第二个参数是可选的,是一个配置对象,目前只有一个属性type,它的值是一个字符串,表示数据的 MIME 类型,默认是空字符串。

示例1:Blob 保存 HTML数据

  1. var htmlFragment = ['<a id="a"><b id="b">hey!</b></a>'];
  2. var myBlob = new Blob(htmlFragment, {type : 'text/html'});

上面代码中,实例对象myBlob包含的是字符串。生成实例的时候,数据类型指定为text/html

示例2:Blob 保存 JSON 数据

  1. var json = { hello: 'world' };
  2. var blob = new Blob([ JSON.stringify(json,null,2) ], {type : 'application/json'});

可以把以下代码直接粘贴到控制台下载文件

  1. function download (url, name) {
  2. const a = document.createElement('a');
  3. a.download = name;
  4. a.rel = 'noopener';
  5. a.href = url;
  6. // 触发模拟点击
  7. a.dispatchEvent(new MouseEvent('click'));
  8. // 或者 a.click();
  9. }
  10. const json = {
  11. a: 3,
  12. b: 4,
  13. c: 5
  14. }
  15. const str = JSON.stringify(json, null, 2);
  16. // 方案一:Text -> DataURL
  17. const dataUrl = `data:,${str}`
  18. download(dataUrl, 'demo.json')
  19. // 方案二:Text -> Blob -> ObjectURL
  20. const url = URL.createObjectURL(new Blob(str.split('')));
  21. download(url, 'demo1.json');
  1. 模拟下载,可以通过新建一个 <a href="url" download><a> 标签并设置 urldownload 属性来下载
  2. 可以通过把 json 转化为 dataurl 来构造 URL
  3. 可以通过把 json 转换为 Blob 再转化为 ObjectURL 来构造 URL

    实例属性

Blob具有两个实例属性sizetype,分别返回数据的大小和类型。

  1. var htmlFragment = ['<a id="a"><b id="b">hey!</b></a>'];
  2. var myBlob = new Blob(htmlFragment, {type : 'text/html'});
  3. myBlob.size // 32
  4. myBlob.type // "text/html"

实例方法

slice

Blob具有一个实例方法slice,用来拷贝原来的数据,返回的也是一个Blob实例。

  1. myBlob.slice(start, end, contentType)

slice方法有三个参数,都是可选的。它们依次是起始的字节位置(默认为0)、结束的字节位置(默认为size属性的值,该位置本身将不包含在拷贝的数据之中)、新实例的数据类型(默认为空字符串)。

Blob 常见用途

input file 获取用户选择的文件信息

文件选择器<input type="file">用来让用户选取文件。出于安全考虑,浏览器不允许脚本自行设置这个控件的value属性,即文件必须是用户手动选取的,不能是脚本指定的。用户选好了文件之后,脚本就可以读取这个文件。

文件选择器返回一个 FileList 对象,该对象是一个类似数组的成员,每个成员都是一个 File 实例对象。File 实例对象是一个特殊的 Blob 实例,增加了namelastModifiedDate属性。

  1. // HTML 代码如下
  2. // <input type="file" accept="image/*" multiple onchange="fileinfo(this.files)"/>
  3. function fileinfo(files) {
  4. for (var i = 0; i < files.length; i++) {
  5. var f = files[i];
  6. console.log(
  7. f.name, // 文件名,不含路径
  8. f.size, // 文件大小,Blob 实例属性
  9. f.type, // 文件类型,Blob 实例属性
  10. f.lastModifiedDate // 文件的最后修改时间
  11. );
  12. }
  13. }

AJAX 请求中获取文件的 Blob 二进制格式数据内容

  1. AJAX 请求时,如果指定responseType属性为blob,获取到响应的就是一个 Blob 对象。 ```javascript function getBlob(url, callback) { var xhr = new XMLHttpRequest(); xhr.open(‘GET’, url); xhr.responseType = ‘blob’; xhr.onload = function () { callback(xhr.response); } xhr.send(null); }

// 返回excel二进制数据 download: function(type = 1) { return new Promise((resolve, reject) => { axios.get(${request.baseurl}service/download/?fileType=${type}, { headers: { “X-Csrftoken”: window.sessionStorage.token }, responseType: ‘blob’, //二进制流 }).then(function(res) { // console.log(‘at getExcel.js download() res ==’, res); resolve(res); }).catch(function(error) { // console.log(‘at getExcel.js download() err ==’, error); errorMsg() reject(error); }); });

}

  1. 2. ajax获取数据后再使用`blob()`方法将文件对应的响应对象转化成 Blob 对象
  2. ```javascript
  3. async function createImageBlob(url) {
  4. const response = await fetch(url);
  5. return await response.blob();
  6. }

将 Blob 生成临时URL 进行预览文件等操作

浏览器允许使用URL.createObjectURL()方法,针对 Blob 对象生成一个临时 URL,以便于某些 API 使用。这个 URL 以blob://开头,表明对应一个 Blob 对象,协议头后面是一个识别符,用来唯一对应内存里面的 Blob 对象。这一点与data://URL(URL 包含实际数据)和file://URL(本地文件系统里面的文件)都不一样。

  1. var droptarget = document.getElementById('droptarget');
  2. droptarget.ondrop = function (e) {
  3. var files = e.dataTransfer.files;
  4. for (var i = 0; i < files.length; i++) {
  5. var type = files[i].type;
  6. if (type.substring(0,6) !== 'image/')
  7. continue;
  8. var img = document.createElement('img');
  9. img.src = URL.createObjectURL(files[i]);
  10. img.onload = function () {
  11. this.width = 100;
  12. document.body.appendChild(this);
  13. URL.revokeObjectURL(this.src);
  14. }
  15. }
  16. }

上面代码通过为拖放的图片文件生成一个 URL,产生它们的缩略图,从而使得用户可以预览选择的文件。
浏览器处理 Blob URL 就跟普通的 URL 一样,如果 Blob 对象不存在,返回404状态码;如果跨域请求,返回403状态码。Blob URL 只对 GET 请求有效,如果请求成功,返回200状态码。由于 Blob URL 就是普通 URL,因此可以下载。

详见《URL对象》一文。