likes
comments
collection
share

Web 轻量上报数据方式介绍与使用总结

作者站长头像
站长
· 阅读数 47

一、背景

日常业务中存在一些通用场景,比如埋点,异常处理,性能监控等等,它们的数据都有以下共性特点。

数据特点:

  • 不要求回调;
  • 数据轻量化(大部分);
  • 不需携带 cookie 凭证(跨域方便);
  • 重点关心是否发送成功(在页面返回,离开,刷新等边缘情景)

二、哪种上报方式比较完美?

市面上存在多种可与服务器进行数据交互的方式,例如 xhr、fetch、script 标签、img 标签、link 标签、CSS 背景图等等,各有各自的优缺点,有没有存在比较完美的方式,既兼顾了用户体验性,又有安全性可靠性,达到业务的要求?这里我们归类一下,针对较为常用的四种上报方式:Ajax, Image, Beacon, fetch 做一下具体分析。

三、特性分析

1. Ajax

特点:

基于 XMLHttpRequest API 实现,在浏览器与 Web 服务器之间使用异步数据传输,被所有的主流浏览器支持。

优点:

  1. 默认异步发送,不会阻塞页面;

  2. POST 方式下数据大小不限制;

  3. 数据存放于 body,安全性较强;

  4. 基本兼容现代所有浏览器;

缺点:

  1. 需要处理跨域限制;

  2. 跳转刷新关闭页面时发送数据效果较差;

  3. 若使用同步模式则阻塞流程影响用户体验;

2. Image

设置 img 标签的 src 属性,将采集的数据转换成字符串拼接在 url 上,并通过 GET 方式向服务端发送数据实现。

var img = new Image();
img.src = url;

特点

优点:

  1. 简单且天然可跨域;

  2. 无阻塞问题;

  3. 兼容所有浏览器;

缺点:

  1. 根据浏览器的不同,数据量有大小限制 2~8 kb;

  2. GET 方式发送,安全性较差(刷量,敏感数据泄漏,浏览器插件干扰);

  3. 跳转刷新关闭页面时发送数据效果一般;

3. Beacon

navigator.sendBeacon 是一个比较新的,底层基于 fetch API 实现的 API,原理是通过将请求放进浏览器发送队列,用户代理在空闲时异步向服务器发送数据,不会延迟页面的卸载或者影响下个页面载入时的性能。

特点

优点:

  1. 异步无阻塞;

  2. 跳转刷新关闭页面时发送数据效果良好;

  3. 数据量限制一般,64k;

  4. 不受跨域限制;

  5. POST 方式发送,安全性强;

  6. 浏览器兼容性中上等(除了 IE 其它都支持);

缺点:

  1. 只能判断出是否放入浏览器任务队列,不能判断是否发送成功;

  2. 不支持自定义请求头;

console.log('Send Beacon: ', navigator.sendBeacon(url, data));
// Send Beacon:  true
// sendBeacon 返回值,如果成功把数据加入传输队列时,返回 true,否则为false

浏览器兼容性(除了 PC 的 IE,还行)

Web 轻量上报数据方式介绍与使用总结

4. fetch

fetch API 提供了一个比 Ajax 更强大和更灵活的功能集,可返回一个 Promise 对象实现对返回结果进行检索,带有 keepalive 属性的 fetch 和 Navigator.sendBeacon() API 类似。

keepalive 属性用于页面卸载时,告诉浏览器在后台保持连接,继续发送数据。一个典型的场景就是,用户离开网页时,脚本向服务器提交一些用户行为的统计信息。这时,如果不用 keepalive 属性,数据可能无法发送,因为浏览器已经把页面卸载了。

特点

优点:

  1. 可配置跨域;

  2. 异步无阻塞,用户体验棒;

  3. POST/GET, 请求头可自定义;

缺点:

  1. keepalive 场景下数据量限制一般,64k;

  2. 浏览器兼容性较差;

fetch(url, {
  method: 'POST',
  body: data,
  keepalive: true,
  // mode: 'cors'
});

浏览器兼容性(稍微差些)

Web 轻量上报数据方式介绍与使用总结

Web 轻量上报数据方式介绍与使用总结

四 、实验结果(可靠性,安全性,用户体验)

1.四种发送方式在(onbeforeunload,onunload,onpopstate)等场景下的对比可见,ajax 方式和不设置 keepalive 属性下的 fetch 方式,表现效果都比 beacon,image 和 fetch(keepalive)差些。

Web 轻量上报数据方式介绍与使用总结

2.数据上报优缺点对比如下

Web 轻量上报数据方式介绍与使用总结

五 、结论(没有最完美的,只有更合适的)

Image:

适合发送数据量小且兼顾浏览器兼容性的场景,例如 Web 页面的页面浏览、元素点击、曝光,性能监控等行为事件;

Ajax:

适合发送数据量较大,依赖回调数据用于前端渲染和具体处理的场景,对用户体验会有一定妥协;

Beacon:

适合需要进行精确统计,页面跳转或关闭等场景做精准监控,选择 Beacon 方式能最大程度保证数据成功率;

fetch:

fetch 有逐渐替代 Ajax 的趋势,但兼容性的路仍然很长。(最艰难的 IE 时代已经被熬过去了)

所以说没有一种数据上报在各个方面都是优秀的,都有一定的优缺点,面对不同的业务需求,有时候可以通过选择不同的上报方式达到理想的要求,有时候也可以通过组合方式来达到 1+1 > 2 的效果,例如神策埋点的组合,优先判断是否兼容 beacon 方式,不兼容情况下再使用 image 方式发送。

奇妙的组合方式:

if (sendType === 'beacon' && typeof navigator.sendBeacon !== 'function') {
  sendType = 'image';
}
转载自:https://juejin.cn/post/7241452578126692413
评论
请登录