本文详细解析在网页卸载(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)技术。
所谓“反弹追踪”,是指当用户点击链接跳转时,页面首先跳转到一个或多个中间网址以收集相关信息,处理完毕后再重定向到最终的目标网址。

// 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追踪用户的资料请关注本站其它相关文章!