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请求,要比模拟表单提交成本低很多)