JavaScript 页面卸载时数据上报的多种实现方案

作者:木棉

时间:2026-10-24

浏览:341

本文详细解析在网页卸载(unload)阶段向服务器发送用户数据的多种 JavaScript 实现方式。内容涵盖同步与异步 AJAX 的局限性及变通技巧、利用 setTimeout 延迟跳转的策略、反弹追踪(Bounce Tracking)机制,以及现代浏览器推荐的 Beacon API 和 HTML5 ping 属性。旨在帮助开发者在保障用户体验的前提下,准确收集用户行为数据。

文章目录

一、同步 AJAX

将收集到的用户数据通过 AJAX 请求发送至服务器,是常见的做法,通常将其放置在 unload 事件处理器中执行。

然而,在 unload 事件中使用异步 AJAX 并不保证能成功发送数据,因为此时网页正处于卸载过程中,浏览器的行为不确定,可能发送也可能忽略请求。因此,需要改用同步 AJAX 请求来确保数据发出。


window.addEventListener('unload', function (event) {
  let xhr = new XMLHttpRequest();
  xhr.open('post', '/log', false);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send('foo=bar');
});

在上述代码示例中,xhr.open() 方法的第三个参数设置为 false,这明确指定了发起的是同步请求。

这种方法存在一个主要缺陷:现代浏览器逐渐禁止在主线程中使用同步 AJAX。因此,上述代码在实际环境中已无法正常使用。

二、异步 AJAX

异步 AJAX 实际上是可以使用的,但有一个前提条件:在 unload 事件处理器中必须包含一些耗时的同步操作。这些操作可以延长事件的处理时间,从而为异步 AJAX 请求的发送争取足够的时间窗口。


function log() {
  let xhr = new XMLHttpRequest();
  xhr.open('post', '/log', true);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send('foo=bar');
}

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

  // a time-consuming operation
  for (let i = 1; i < 10000; i++) {
    for (let m = 1; m < 10000; m++) { continue; }
  }
});

在上述代码中,通过强制执行双重循环来模拟耗时操作,从而延长 unload 事件的执行时间,确保异步 AJAX 请求能够成功发出。

三、追踪用户点击

使用 setTimeout 也可以延迟页面卸载过程,从而保证异步请求能够成功发送。以下是一个追踪用户点击行为的示例。


// HTML 代码如下
// <a id="target" href="https://baidu.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >click</a>
const clickTime = 350;
const theLink = document.getElementById('target');

function log() {
  let xhr = new XMLHttpRequest();
  xhr.open('post', '/log', true);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send('foo=bar');
}

theLink.addEventListener('click', function (event) {
  event.preventDefault();
  log();

  setTimeout(function () {
    window.location.href = theLink.getAttribute('href');
  }, clickTime);
});

上述代码通过 setTimeout 设置了 350 毫秒的延迟,使得页面在跳转前等待这段时间,从而让异步 AJAX 请求有足够的时间发出。

四、反弹追踪

除了上述方法,追踪用户点击还可以采用反弹追踪(bounce tracking)技术。

所谓“反弹追踪”,是指当用户点击链接跳转时,页面首先跳转到一个或多个中间网址以收集相关信息,处理完毕后再重定向到最终的目标网址。

一、同步 AJAX


// HTML 代码如下
// <a id="target" href="https://baidu.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow" >click</a>
const theLink = document.getElementById('target');

theLink.addEventListener('click', function (event) {
  event.preventDefault();
  window.location.href = '/jump?url=' + 
    encodeURIComponent(theLink.getAttribute('href'));
});

在上述代码中,用户点击时会强制跳转至一个中间网址,并将相关信息携带过去,待信息处理完成后,再跳转到原始的目标网址。

目前,谷歌和百度等搜索引擎均采用这种方式,用户点击搜索结果时,会经过多次反弹跳转,最终才到达目标网址。

五、Beacon API

上述所有方法都会导致网页卸载过程的延迟,从而严重影响用户体验。

为了解决网页卸载时异步请求无法成功发送的问题,浏览器专门实现了 Beacon API。该 API 允许异步请求脱离当前主线程,交由浏览器进程独立发送,从而确保请求一定能被发出。


window.addEventListener('unload', function (event) {
  navigator.sendBeacon('/log', 'foo=bar');
});

在上述代码中,navigator.sendBeacon() 方法可以确保异步请求一定会被发出。该方法的第一个参数是请求的目标网址,第二个参数是要发送的数据。

需要注意的是,Beacon API 发出的是 POST 请求。

六、ping 属性

HTML 的 <a> 标签提供了一个 ping 属性。只要用户点击该链接,浏览器就会向该属性指定的网址发送一个 POST 请求。


<a href="https://baidu.com" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  ping="/log?foo=bar">
  click
</a>

在上述代码中,当用户点击并跳转时,会向 /log 这个网址发送一个 POST 请求。

ping 属性无法指定数据体,因此信息似乎只能通过 URL 的查询字符串来携带。

以上就是如何用JS追踪用户的详细内容,更多关于用JS追踪用户的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章