JavaScript Blob对象详解

Blob对象为大二进制对象,一个Blob对象就是一个包含有只读原始数据的类文件对象。

一、构造函数

Blob构造函数接受两个可选参数,第一个参数为一个数组,数组的元素可以是任意多个的ArrayBuffer,ArrayBufferView (typed array), Blob,或者 DOMString对象。
第二个参数为一个对象,设置Blob对象的属性

二、方法

slice:返回一个新的Blob对象,它截取了原对象中的一部分内容。
slice方法支持三个可选参数,分别是start、end、contentType
第一个参数start为起始索引,默认为0
第二个参数end为结束索引,默认为最后一个索引
第三个参数contentType为新生成的Blob对象的MIME类型,默认为空字符串
如果start的值大于原始Blob的值,则新生成的Blob对象大小为0,内容是空的。

三、MIME类型

构造函数的第二个参数一般用于设置MIME类型,例如:

  new Blob(['test'], {type:'text/plain'});

上面的例子中Blob对象的类型为text/plain,内容为test
设置MIME类型的主要目的是让浏览器知道该如何显示该二进制资源(例如,是图片则显示图片,是网页则解析HTML,是二进制文件则弹出下载框等)

四、示例
下面的例子可以复制到浏览器的控制台中,并将返回的blob:开头的url复制粘贴到地址栏中,就可以看到效果。
显示文本:

  var blob = new Blob(['纯文本'],{type: 'text/plain'});
  URL.createObjectURL(blob);

显示网页:

 var blob = new Blob(['<html><head><title>我是标题</title></head>', '<body><h1>我是内容</h1></body></html>'],{type: 'text/html'});
 URL.createObjectURL(blob);

显示一个json:

  var blob = new Blob([JSON.stringify({"key":"value"})], {type:'text/json'});
  URL.createObjectURL(blob);

作为二进制文件下载:

  var blob = new Blob(['文件内容'], {type:'application/octet-binary'});
  URL.createObjectURL(blob);

五、兼容性

IE:10+
Firefox:13+
Chrome:20+
Safari:6+
Opera:12.1+

Beacon API介绍

Beacon API可以向指定服务器发送少量的数据以实现统计等目的。

一、应用场景

主要用于记录并发送用户行为、发送错误日志等。
之前记录用户行为通常是通过发送一个GET请求(一般是一个带所有统计信息参数的图片请求),使统计服务器获取到用户行为数据并记录。
这种方式有以下几个弊端:
1.当页面关闭时,发送的统计请求可能不会成功,导致统计数据丢失
2.通常为了解决关闭页面的统计数据丢失问题,会发起一个同步的请求,这样会阻塞页面的卸载
3.GET请求通常有长度限制,可携带的数据量有限,并且一般只能携带文本信息
而使用Beacon API后,上述问题都能够解决:
Beacon是以非阻塞POST的方式发送数据,支持多种数据类型:ArrayBufferView, Blob, DOMString, 或者 FormData 类型的数据
关闭页面不会中断Beacon的发送,也不会阻塞页面的卸载,用户体验更好

二、API用法

navigator.sendBeacon(url, data);
url 参数表明 data 将要被发送到的网络地址。(不存在跨域问题,但https的页面中不能向http协议的统计服务器发送数据,会报安全错误)
data 参数是将要发送的 ArrayBufferView, Blob, DOMString, 或者 FormData 类型的数据。
sendBeacon() 方法返回 true 如果用户代理能够成功地将要发送的数据排入队列,否则返回 false。
示例:

document.getElementById('container').addEventListener('click', function(e){
   if(e.target.tagName === 'A'){
      var formData = new FormData();
      formData.append('type', 'click');
      formData.append('elementType', 'link');
      formData.append('href', e.target.href);
      formData.append('t', Date.now());
      navigator.sendBeacon('http://tongji.example.com', formData);
   }
}, false);

window.addEventListener('unload', function(){
    var data = JSON.stringify({
        type: 'unload',
        t: Date.now()
      });
    navigator.sendBeacon('http://tongji.example.com', data);
}, false);

上面示例中,为container下的所有A标签的点击事件进行了统计,当点击链接时,会发送统计信息到统计服务器tongji.example.com上,并以form表单的形式发送。
在页面卸载时,也会将相关信息以json字符串的方式发送给统计服务器
注意此例为了演示不同的发送方式采用了两种不同的数据类型,实际使用时建议同一使用一种数据类型便于统计处理。

三、兼容性

IE:不支持
Edge:14+
Firefox:31+
Chrome:39+
Opera:26+

四、注意事项

该API没有响应回调方法,所以建议服务器返回204状态码
该API同样可以应用于一些只需要发送数据而不需要关心返回结果的场景(如CSRF攻击中使用此API构造POST请求,要比模拟表单提交成本低很多)