最近项目是一个聊天系统,在做客服这块的时候,顾客客户端那边如果窗口关闭的话,监听窗口关闭时间,然后调用退出登录的接口,实现客户端下线的功能。但是过程中遇到比较多的坑。
比如:
区分窗口关闭和刷新事件
火狐浏览器兼容
关闭发退出登录请求,必须使用原生或者$ajax发同步,axios不支持同步
App.vue 页面代码实现
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
_beforeUnload_time: 0,
_gap_time: 0,
is_fireFox: navigator.userAgent.indexOf("Firefox") > -1,
};
},
methods: {
beforeunloadHandler(e) {
this._beforeUnload_time = new Date().getTime();
},
unloadHandler(e) {
this._gap_time = new Date().getTime() - this._beforeUnload_time;
//判断是窗口关闭还是刷新
localStorage.setItem('time',this._gap_time)
if (this._gap_time <= 5) {
// 发送设置同步 (退出登陆的api)
var xhr = new XMLHttpRequest();
xhr.open("DELETE", '.' + this.$http.logout, false);
xhr.setRequestHeader('Authorization','Bearer'+sessionStorage.getItem('token'))
xhr.send();
}
},
},
},
mounted() {
window.addEventListener("beforeunload", e => {
this.beforeunloadHandler(e)
let userAgent = navigator.userAgent
let isOpera = userAgent.indexOf("Opera") > -1;
if (isOpera) { //判断是否Opera浏览器
return "Opera"
};
if(userAgent.indexOf("Firefox") > -1){
this.unloadHandler();
}else if(userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera){
e = e ? e : (window.event ? window.event : null);
var cy = e.clientY || e.target.event.clientY;
var ak = e.altKey || e.target.event.altKey;
if (cy < 0 || ak) {
this.unloadHandler();
}
}
});
window.addEventListener("unload", async e => {
this.unloadHandler(e)
});
},
destroyed() {
window.removeEventListener("beforeunload", e =>
this.beforeunloadHandler(e)
);
window.removeEventListener("unload", e => this.unloadHandler(e));
},
};
</script>
<style>
</style>