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

getBattery API用法详解

本文介绍getBattery API的使用方法及注意事项。getBattery API是获取电源管理信息的API。

本文内容可以在https://www.lyz810.com/demo/battery/中查看相关Demo。
一、概述
navigator.getBattery是一个用于获取电源管理信息的API。它可以获取电源的连接状态、电池电量水平、剩余放电时间、剩余充电时间等于电源管理相关的参数。

二、兼容性
navigator.getBattery基本只能在Chrome及Firefox浏览器上使用,其他浏览器基本上都没戏。
Firefox:43+
Chrome:38+
Opera:25+

三、基本用法

  navigator.getBattery().then(function(batteryInfo){
    console.log(batteryInfo);
  });

navigator.getBattery返回一个Promise对象,通过then的第一个function,可以获取到电池状态信息。
其中batteryInfo对象如下:
batteryInfo.charging:电源状态,true表示电源接通(但是否充电不一定),false表示电源没有接通。
batteryInfo.chargingTime:充电时长,目前测试没有发现此数值除Infinity外还有其他值,可能与系统等因素有关。
batteryInfo.dischargingTime:剩余时长,在不接电源时此属性会有一个非Infinity的值,表示电池剩余时间的秒数。
batteryInfo.level:电池电量水平,范围0~1表示0%~100%。
batteryInfo.onchargingchange:当切换电源状态时触发,如插入电源和拔出电源。
batteryInfo.onchargingtimechange:目前未发现会触发事件,因为chargingTime总是Infinity。
batteryInfo.ondischargingtimechange:电池剩余时间改变时触发该事件。
batteryInfo.onlevelchange:在电池电量水平改变时触发。

四、注意事项
Firefox中电量水平的精度为0.1,会对电量进行四舍五入,如电量为95%时,Firefox电量显示为100%(1),当电量为94%时,Firefox电量显示为90%(0.9)
Chrome中电量水平的精度为0.01,能够精确的获取1%的电量差距
电池剩余时间估算可能与系统的电池剩余时间不同