浏览器及标签页关闭时登出的解决方案

一、前言

项目出于安全评测的要求,需要页面在浏览器及其标签页关闭的时候登出,保证每次进入系统都重新登录。 核心处理逻辑有如下几点:

  1. 监听浏览器关闭事件
  2. 关闭时清除本地存储的token
  3. 关闭时调用登出接口保证后端redis中token被清除

通过AI和网络搜索 给出的方案,很快就实现了。但在自测验证过程中,发现有两个费劲周折的问题。

  1. beforeunload 事件在页面刷新时也会触发,而排除是刷新的情况 试了N种方案都不尽人意
  2. 标签页关闭后axios触发的登出请求 会被浏览器取消,后端接收不到。

折腾一波后,最终都解决了,这里记录下解决方案。

二、解决方案

2.1 标签页关闭时登出,但排除刷新的场景

在unload事件中增加刷新情况的判断。除了下面代码中时间差的判断方法外,还尝试过performance.navigation等方案,都无效。

javascript 复制代码
let _beforeUnload_time = 0
let _gap_time = 0
window.onbeforeunload = () => {
  _beforeUnload_time = new Date().getTime();
  console.log("beforeUnload_time", _beforeUnload_time);
};

window.onunload = (event) => {
  _gap_time = new Date().getTime() - _beforeUnload_time;
  console.log("gap_time", _gap_time);
if (_gap_time <= 5 || event.altKey) {
    // 执行关闭需要进行的操作,1. 清除本地缓存;2. 发送登出接口
    console.log("xxxxxxx关闭");
  }else{
    console.log("页面刷新");
  }
};

2.2 登出请求,避免被浏览器取消

Fetch的keepalive可以在页面卸载(如用户关闭标签页或跳转到新页面)后,确保请求仍能在后台完成的选项

php 复制代码
fetch('/api/logout', {
  method: 'GET',
  headers: {
    'Authorization': token
  },
  keepalive: true, // 类似 sendBeacon 的行为
});

2.3 浏览器关闭再进入的场景

基于sessionStorage做判断,存储在 sessionStorage 里面的数据在页面会话结束时会被浏览器自动清除。

arduino 复制代码
// 初次进入跳转登录页面
if (!sessionStorage.getItem("entered")) {
  location.hash = "#/login";
  sessionStorage.setItem("entered", "true");
}

三、参考资料

相关推荐
FungLeo7 小时前
成为全栈·React 管理后台篇·总复盘:从“接口能调通”到“后台值得使用”
前端·react.js·前端框架·项目复盘·成为全栈
Csvn9 小时前
并发模式:让渲染学会排队、插队和让路
前端
可乐鸡翅yeah_9 小时前
新手梳理:M3U8 线上问题,哪些是前端锅,哪些是后端锅
前端·ios·音视频·实时音视频·m3u8·音视频在线播放
Flynt9 小时前
Linear 用 1000 个 PR 换掉 styled-components,我写了 200 个按钮,把这笔账复现了一遍
前端·css·preact
JavaGuide10 小时前
NVIDIA 又开源了!这次给 AI Agent 加上权限管控
前端·后端
excel10 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
莪_幻尘11 小时前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm
风骏时光牛马11 小时前
AI模型综合能力评测:性能、指令遵循与多场景实测对比
前端
Frag0ut12 小时前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
hiahiahia12312 小时前
实现完整 Tool Dispatcher
开发语言·前端