页面关闭,也能将统计数据发送到Web 服务器

页面关闭(前/时/后)将统计数据发送到 Web 服务器的方案:

一、XMLHttpRequest

缺点:定时器(setInterval)间隔时间不好把握,Ajax 也会浪费大量的资源。

setInterval(() => {
    $.ajax({
        type: "method",
        url: "url",
        data: "data",
        dataType: "dataType",
        success: function (response) {
            
        }
    });
}, interval);

二、beforeunload

当浏览器窗口关闭或者刷新时,会触发 beforeunload 事件。当前页面不会直接关闭,可以点击确定按钮关闭或刷新,也可以取消关闭或刷新。

window.addEventListener('beforeunload', function (event) {
  // Cancel the event as stated by the standard.
  event.preventDefault();
  // Chrome requires returnValue to be set.
  event.returnValue = '';
});

三、unload

当文档或一个子资源正在被卸载时, 触发 unload 事件。

window.addEventListener('unload', function(event) {
  console.log('unload');
});

方案二和方案三的缺点:

  • 无法获取用户取消/确认的回调
  • 无法区分刷新/关闭

四、websocket

双方发送数据很及时。若客户端离线,服务器端马上就知道了。
但若只是个小项目,感觉有点重了。

五、img元素

创建一个 img 元素并设置 src,但是大部分浏览器会延迟卸载(unload)文档以加载图像。

六、Beacon【推荐】

特点:

  • 通过 HTTP POST 将少量数据(<64 KB)异步传输,可靠性好
  • 这个请求不需要响应,保证在页面的 unload 状态从发起到完成之前被发送。
  • 不会阻塞页面卸载,也就不会影响下一导航的载入
  • 支持跨域
  • 不支持自定义请求头

语法:

navigator.sendBeacon(url);
navigator.sendBeacon(url, data);

示例1:

window.addEventListener('unload', function (event) {
  const data = {name: "beacon"};
  navigator.sendBeacon('/log', JSON.stringify(data));
});

示例2:

document.addEventListener('visibilitychange', function logData() {
  if (document.visibilityState === 'hidden') {
    navigator.sendBeacon('/log', analyticsData);
  }
});

七、Fetch keep-alive

keepalive 属性用于页面卸载时,告诉浏览器在后台保持连接,继续发送数据。带有 keepalive 标志的 Fetch 是 Navigator.sendBeacon() API 的替代品。

同样典型的场景就是用户离开网页时,向服务器提交一些用户的行为统计数据。

开启了 keepalive 属性后,网页就算被关闭了,请求被会继续执行而不会中断。

示例:

 window.onunload = function() {
   fetch('/analytics', {
     method: 'POST',
     body: "statistics",
     keepalive: true
   });
 };

相比 Beacon API,他有这么一些好处:能自定义请求头,不仅仅局限于 POST 请求…

总之只是在 Fetch 添加了一个 keepalive 属性,所以就把他当作一个正常的 Fetch 请求使用就行。

原文:页面关闭,也能将统计数据发送到Web 服务器? (xushanxiang.com)

posted @ 2022-04-06 16:04  许善祥  阅读(327)  评论(0编辑  收藏  举报