如果远程可行,请更改要求,因为这会导致不太理想的用户体验。
至少在某些浏览器上,您可以从 onbeforeunload 处理程序执行 同步 ajax 请求,以向您的服务器发送用户正在离开页面的信息:
window.onbeforeunload = function() {
$.ajax({
url: "/path/to/page",
data: {/* ...stuff... */,
async: false // <== Option is being removed soon
});
};
我说这是一个糟糕的用户体验的原因是,由于 ajax 调用是同步,它会阻止它们,并且在某些浏览器上相当侵入(整个事情在等待请求时锁定去完成)。这也是为什么它可能不是可靠的跨浏览器。
jQuery 团队将在某个时候从ajax 中删除async 选项。它仍然存在于底层的 XMLHttpRequest 对象中,因此当发生这种情况时,您可以直接使用它。
用户离开网站的事实在网络服务器日志中已经很明显了,尽管您无法确定他们在最终页面上停留了多长时间。如果“他们在最后一页上花了多长时间”是非常重要的信息,而不是在他们离开时阻止他们(并且依赖于可能不是完全可靠的跨浏览器的东西),你当它们仍在页面上时,可以使用背景“ping”。随着时间的推移,最好将 ping 间隔越来越远。
例如,当页面加载时:
(function($) {
var SECOND = 1000;
var MINUTE = 60000;
var arrived = +new Date();
var pingTimes = {
0: 10 * SECOND, // Every 10 seconds in first minute
1: 30 * SECOND, // Every 30 seconds in second minute
2: 45 * SECOND, // Every 45 seconds in third minute
other: 60 * SECOND, // Every minute otherwise
long: 10 * MINUTE // Every 10 minutes if they've been here a long time
};
nextPing();
function ping() {
$.ajax({
url: "/path/to/ping/page",
method: "POST",
success: nextPing,
error: nextPing
});
}
function nextPing() {
var elapsed, pingTime;
// Get the # of full minutes they've been here
elapsed = Math.floor((new Date() - arrived) / MINUTE);
// If it's been a long time, use `pingTimes.long`.
// Otherwise, use the time from the table or the default.
pingTime = elapsed > 15 * MINUTE ? pingTimes.long : (pingTimes[elapsed] || pingTimes.other);
setTimeout(ping, pingTime);
}
})(jQuery);