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

如何实现用户离开项目网页时触发登出(排除站内跳转)

解决站内跳转触发beforeunload登出的问题

我明白你的痛点——beforeunload事件太"灵敏"了,不管是跳站内页面、刷新还是关窗口都会触发,完全不符合你只想在跳外部或关窗口时登出的需求。下面给你一套可行的解决方案,分步骤来:

核心思路

我们需要给页面加一个"状态标记",区分用户当前的操作是站内跳转还是外部跳转/关闭窗口/刷新,只有后者才触发登出逻辑。

具体实现步骤

1. 添加全局状态标记

在所有非index.html的页面脚本开头,定义一个全局变量用来标记是否是站内跳转:

// 全局标记:是否为站内跳转
let isInternalNavigation = false;

2. 监听所有站内链接的点击事件

给页面上所有<a>标签添加点击监听,判断目标链接是否是站内地址,如果是就把标记设为true:

document.addEventListener('click', function(e) {
  // 找到点击的a标签(考虑嵌套元素的情况)
  const targetLink = e.target.closest('a');
  if (!targetLink) return;

  const linkHref = targetLink.getAttribute('href');
  if (!linkHref) return;

  // 判断是否为站内链接:相对路径、当前域名的绝对路径都算
  const isInternal = linkHref.startsWith('/') || 
                    linkHref.startsWith('./') || 
                    linkHref.startsWith('../') || 
                    linkHref.includes(window.location.host);

  if (isInternal) {
    isInternalNavigation = true;
    // 跳转后重置标记,避免影响后续操作
    setTimeout(() => {
      isInternalNavigation = false;
    }, 100);
  }
});

3. 修改beforeunload事件逻辑

在原来的beforeunload监听里,先检查全局标记,只有非站内跳转时才执行登出:

$(window).on("beforeunload", function() {
  // 仅当不是站内跳转时,才触发登出
  if (!isInternalNavigation) {
    logoutAccount(false);
  }
});

4. 额外处理页面刷新的情况(可选)

如果你希望用户刷新页面时也保持登录状态(而不是触发登出),可以再加一层判断:

// 页面加载时标记是否为刷新操作
window.addEventListener('load', function() {
  const navEntry = performance.getEntriesByType("navigation")[0];
  // 标记当前是否是刷新页面
  if (navEntry && navEntry.type === 'reload') {
    sessionStorage.setItem('isPageRefresh', 'true');
  } else {
    sessionStorage.removeItem('isPageRefresh');
  }
});

// 修改beforeunload逻辑,排除刷新场景
$(window).on("beforeunload", function() {
  const isRefresh = sessionStorage.getItem('isPageRefresh') === 'true';
  // 非站内跳转 + 非刷新,才触发登出
  if (!isInternalNavigation && !isRefresh) {
    logoutAccount(false);
  }
});

5. 处理JS主动跳转的场景(可选)

如果你的页面里有用JS触发的跳转(比如window.location.href = 'home.html'),记得手动设置标记:

// 封装一个站内跳转的函数
function goToInternalPage(url) {
  isInternalNavigation = true;
  window.location.href = url;
  setTimeout(() => {
    isInternalNavigation = false;
  }, 100);
}

// 使用示例:
// goToInternalPage('statistics.html');

最终的登出相关代码整合

把上面的代码整合后,你的非index.html页面脚本里的登出部分会变成这样:

let isInternalNavigation = false;

// 监听站内链接点击
document.addEventListener('click', function(e) {
  const targetLink = e.target.closest('a');
  if (!targetLink) return;

  const linkHref = targetLink.getAttribute('href');
  if (!linkHref) return;

  const isInternal = linkHref.startsWith('/') || 
                    linkHref.startsWith('./') || 
                    linkHref.startsWith('../') || 
                    linkHref.includes(window.location.host);

  if (isInternal) {
    isInternalNavigation = true;
    setTimeout(() => {
      isInternalNavigation = false;
    }, 100);
  }
});

// 页面加载标记刷新状态
window.addEventListener('load', function() {
  const navEntry = performance.getEntriesByType("navigation")[0];
  if (navEntry && navEntry.type === 'reload') {
    sessionStorage.setItem('isPageRefresh', 'true');
  } else {
    sessionStorage.removeItem('isPageRefresh');
  }
});

function logoutAccount(redirect) {
    if(localStorage['loggedAccount']){
        var account=JSON.parse(localStorage['loggedAccount']);
        var logoutRequest=new XMLHttpRequest();
        logoutRequest.open('GET',url+"/logout/"+account.id,false);
        logoutRequest.send(null);
        localStorage.removeItem('loggedAccount');
        if(redirect){
            window.location.replace("index.html");
        }
    }else{
        if(redirect){
            window.location.replace("index.html");
        }
    }
}

document.getElementById("logoutButton").addEventListener("click",function () {
    logoutAccount(true);
});

$(window).on("beforeunload", function() {
  const isRefresh = sessionStorage.getItem('isPageRefresh') === 'true';
  if (!isInternalNavigation && !isRefresh) {
    logoutAccount(false);
  }
});

这样修改后,用户在站内页面间跳转、刷新页面都不会触发登出,只有跳转到外部链接或者关闭窗口时才会执行登出逻辑,完美符合你的需求~

内容的提问来源于stack exchange,提问作者Mr.D

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:28:33