需求概述
需求:统计用户的登录登出率。
方案:用户登录、关闭浏览器或者标签页时向后端发送请求,用以统计登录/登出时间、登录率
解决方案
export default {
name: 'APP',
mounted() {
this.watchTabUnload()
},
methods: {
watchTabUnload() {
let beginTime = 0;
let differTime = 0;
let _this = this;
window.unload = function() {
if(!navigator.sendBeacon) return
differTime = new Date().getTime() - beginTime;
// differTime 表示 beforeUnload 与 unload 执行的时间差,设置为50ms左右较为合适
if(differTime < 50) {
// 向后端发送请求
const url = 'http://10.221.20.1/lrze/dbsj';
let formData = new FormData();
formData.append('token', localStorage.getItem('token'));
formData.append('userId', localStorage.getItem('userId'));
// 此处不建议使用XMLHttpRequest对象发送数据。这样做请求发送成功概率很低,因为XMLHttpRequest对象是异步发送,存在即将发送的时候,页面已经卸载,从而导致发送取消或者发送失败的情况。
// navigator.sendBeacon()方法请求也是异步的,但是请求与当前页面脱钩,作为浏览器的任务,可以保证会把数据发出去,不拖延卸载流程
navigator.sendBeacon(url, formData)
}
},
window.onbeforeunload = function() {
beginTime = new Date().getTime()
}
}
}
}
注意事项
1、上述代码是监听浏览器或标签页关闭相关代码。用户登录的话,只要登录时向后端发送请求即可
2、监听浏览器的关闭事件代码应放在项目的入口文件中,如果放在其他vue文件中,监听事件可能不会全局生效,所以默认写在app.vue文件中
3、differTime是用来区分浏览器关闭和刷新操作的。经测试,differTime在10~50ms区间都行,此处设置为50ms,是为了保证大概率触发,不建议设置小于10ms,经实测,多数关闭浏览器情况下,differTime < 10 都是不成立的
4、实际测试中,使用axios请求时,后端接收到请求概率为10%左右。而使用navigator.sendBeancon(),后端接收到请求的概率为80%~100%
写在最后:上述方法并不能保证后端能100%接收到请求,实际测试成功率为80%以上,如果有更好建议可以留言,谢谢!