You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS如何在浏览器或标签页关闭时调用log out api

浏览器/标签页关闭时自动触发登出API的实现方案

首选实现方案:beforeunload 结合 sendBeacon

这是目前兼容性和体验最优的方案,sendBeacon是浏览器专门为页面卸载场景设计的API,会保证请求异步发送且不阻塞页面关闭,就算标签页已经销毁,浏览器也会在后台尽力完成请求发送。
实现代码如下:

window.addEventListener('beforeunload', () => {
  // 构造登出接口需要的参数
  const logoutParams = new FormData();
  logoutParams.append('user_token', localStorage.getItem('current_user_token'));

  // 发送登出请求
  const requestQueued = navigator.sendBeacon('/api/user/logout', logoutParams);

  // 当sendBeacon入队失败(如数据超出64KB上限)时,用带keepalive属性的fetch降级
  if (!requestQueued) {
    fetch('/api/user/logout', {
      method: 'POST',
      body: logoutParams,
      keepalive: true
    });
  }
});

兜底补充方案:visibilitychange 事件适配极端场景

部分极端场景下beforeunload不会触发,比如移动端将浏览器切后台后被系统回收进程、用户强制结束浏览器进程等,可以用visibilitychange事件做兜底:

document.addEventListener('visibilitychange', () => {
  // 页面切换为不可见状态时触发登出
  if (document.visibilityState === 'hidden') {
    const logoutParams = new FormData();
    logoutParams.append('user_token', localStorage.getItem('current_user_token'));
    navigator.sendBeacon('/api/user/logout', logoutParams);
  }
  // 可选:用户切回页面时调用会话续期接口恢复登录状态
  if (document.visibilityState === 'visible') {
    fetch('/api/session/renew', {
      method: 'POST',
      credentials: 'include'
    });
  }
});

关键注意事项

  • 不要在卸载事件中使用普通异步fetch/异步XHR:页面卸载进程启动后,所有异步请求会被直接中断,无法成功发送
  • 不建议使用同步XHR作为实现方案:同步请求会阻塞页面卸载流程,用户需要等待请求完成才能关闭标签页,体验极差,且目前多数主流浏览器已经在页面卸载场景下禁用了同步XHR
  • 没有方案可以100%覆盖所有关闭场景:设备断电、系统强制杀进程等极端情况无法触发浏览器事件,建议后端配合设置会话过期机制,长时间无操作后自动失效会话,弥补前端方案的覆盖缺口
  • 单页应用路由跳转不要绑定该逻辑:仅页面真正卸载时需要触发,路由切换属于页面内逻辑,不需要触发登出

内容的提问来源于stack exchange,提问作者Aniket Deshpande

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 07:18:03