监听浏览器关闭时需要【发送请求给后端】清除token,不受刷新和关闭标签页影响,有人搞过吗?
给了其它方案给设计师,但他们安全那边就是要关闭浏览器时就得发送请求给后端使token过期
监听浏览器关闭时需要【发送请求给后端】清除token,不受刷新和关闭标签页影响,有人搞过吗?
给了其它方案给设计师,但他们安全那边就是要关闭浏览器时就得发送请求给后端使token过期
要在浏览器关闭时发送请求使token过期,并且不受刷新和关闭标签页的影响,你可以使用beforeunload
事件。这个事件会在窗口、文档及其资源将要卸载时触发。你可以在这个事件的处理函数中发送一个请求到后端来使token过期。
下面是一个简单的示例代码,演示了如何使用beforeunload
事件来发送请求使token过期:
window.addEventListener('beforeunload', function (e) {
// 在这里发送请求到后端使token过期
// 你可以使用fetch、axios或其他你喜欢的HTTP库来发送请求
fetch('/api/token/expire', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ token: 'your_token_here' }), // 将要过期的token作为请求体发送
})
.then(response => {
// 处理响应,如果需要的话
})
.catch(error => {
// 处理错误,如果需要的话
});
// Chrome要求返回一个非空字符串,否则不会触发事件
e.preventDefault();
e.returnValue = '';
});
请注意,由于浏览器安全策略的限制,beforeunload
事件的处理函数在大多数浏览器中是异步执行的,这意味着你不能在这个函数中等待异步操作(如HTTP请求)完成。因此,你可能需要采取其他策略来确保token在浏览器关闭之前被成功过期,例如使用WebSockets或其他长连接技术。
此外,还需要注意的是,即使你成功地在浏览器关闭时发送了使token过期的请求,仍然有可能存在一些边缘情况,例如用户直接关闭计算机或杀死浏览器进程,导致请求无法成功发送。因此,后端应该有一个机制来处理这种情况,例如设置一个token的过期时间,并在验证token时检查它是否已经过期。
Beacon API 用于发送异步和非阻塞的信标请求。信标请求不需要响应,且浏览器保证在页面卸载前初始化并运行完成。
或者每隔一段时间(如一分钟)发送一次请求,当后端超过一端时间没有收到请求时就认为 token 过期。
做不到,至少公域浏览器做不到。如果你们是内部需求,可以搞一些奇奇怪怪的方案,否则的话就很难。
哦,我想到一个方案,用 service worker 的 notification API,跟服务器做心跳,断了就过期 token。
这个做过类似的,但是我只做了Chrome浏览器,我当时做的时候关闭浏览器的时候清除本地的localStorage,然后使用onbeforeunload
去做的话,无法实现,看到一篇文章中说浏览器刷新和关闭的时候load
事件会有时间差的存在,于是我采用了这样的办法。但是记住我只测试了Chrome浏览器,而且这种方式不知道适不适合你们那么严格的要求。代码如下:
// 判断是刷新还是关闭浏览器,刷新不删除localStorage,否则删除
onMounted(() => {
let beforeTime = 0,
leaveTime = 0;
window.onunload = () => {
leaveTime = new Date().getTime() - beforeTime;
if (leaveTime <= 5) {
console.log("====关闭=====");
localStorage.clear();
} else {
console.log("====刷新=====");
}
};
window.onbeforeunload = () => {
beforeTime = new Date().getTime();
};
});
今天回答了一个类似的问题你可以参考一下 怎么在页面刷新/关闭之前发送个请求, 且不想要提示框 ?
但是如果项目会打开多页签的,那么就不太适合这样的处理,会比较麻烦。其实把 token
间隔设置短一些,然后加上 refresh_token
其实就好了。
主要就是两个方案:
使用Beacon结合visibilitychange事件
很多统计用户页面停留时间就是这么干的
注意不要用 unload 或 beforeunload 事件
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "hidden") {
navigator.sendBeacon("/log", data);
}
});
这个需求其实就是想让客户端浏览器主动通知服务器 token 需要过期,用浏览器关闭的方式还是有很多方式可以绕开的:断网、关机都不会触发浏览器的关闭事件。如果非要按照这个需求去处理,你还不如结合 websocket 用长连接方式,断开连接后服务端就把对应连接关联的 token 给过期掉,这种可能更靠谱点(当然也会有其他问题,看取舍了)。
8 回答6k 阅读✓ 已解决
9 回答9.4k 阅读
6 回答5k 阅读✓ 已解决
5 回答3.6k 阅读✓ 已解决
4 回答8k 阅读✓ 已解决
7 回答10k 阅读
5 回答7.3k 阅读✓ 已解决
做过这个功能,但只适合主流浏览器,代码如下:
如果想更好的解决这个问题,建议使用socket做心跳连接,一直ping,如何断开连接,表示浏览器关闭了,这时候后端处理这个逻辑。
问题:有没有可能同一个浏览器打开了多个页面,我只关闭了其中一个页面,但是我切换了另外一个页面时,并不想退出登录,那么我们应该在这个浏览器关闭这个域名的最后一个网页时处理这个逻辑。
所以我们应该记住当前浏览器打开几个页面: