当浏览器关闭时如何注销用户

6

我希望在用户关闭浏览器时注销其账户。为此,我进行了一些研究并发现以下代码将在我们关闭浏览器时触发。

window.onbeforeunload = function() {
  myService.logout();
  return 'Your own message goes here...';
}

当我尝试关闭浏览器时,此事件将触发并使用户注销。但问题是当页面被重定向时,此事件也会触发。

我想使用此功能使用户注销。但是目前出现了问题,请帮助我实现此功能。


2
所以这不是单页应用?如果您有2个窗口打开并关闭一个窗口呢?仍然想要执行注销操作? - Koushik Chatterjee
是的,我的应用程序是Web应用程序,即使有两个选项卡打开,我也想执行注销。 - Gen
1
由于您正在使用AngularJS,请处理$rootScope中的$destroy事件。 - Koushik Chatterjee
@KoushikChatterjee,请问您能给我提供一段示例代码吗? - Gen
3
请实现会话超时功能。无法确定用户何时“离开”。 - Pointy
显示剩余3条评论
3个回答

2

但是问题在于当页面被重定向时,这个事件也会触发。

我猜测这是你自己执行的重定向。如果是这样的话,为什么不使用全局变量来区分你的重定向和客户端的重定向呢?像这样:

...
thisismyredirect = true; //before redirecting, set this variable
window.location = "http://www.yoururl.com";
...

在你的onbeforeunload事件中,你需要检查这个重定向是否是由你执行的。如果是,那么就不需要调用logout()函数:

window.onbeforeunload = function() {
    if(!thisismyredirect) {
        myService.logout();
        return 'Your own message goes here...';
    }
}

1
另一种解决方案是使用Window.sessionStorage。当用户登录时,将sessionStorage变量设置为“true”,当他们退出时将其设置为“false”,并且在浏览器关闭时,该变量将从sessionStorage中删除。如果您需要在同一浏览器实例的选项卡之间共享sessionStorage变量,则已发布了一个很好的示例here

0
tabOrBrowserStillAliveInterval;

constructor() {
  // system should logout if the browser or last opened tab was closed (in 15sec after closing)
  if (this.wasBrowserOrTabClosedAfterSignin()) {
    this.logOut();
  }

  // every 15sec update browserOrTabActiveTimestamp property with new timestamp
  this.setBrowserOrTabActiveTimestamp(new Date());
  this.tabOrBrowserStillAliveInterval = setInterval(() => {
    this.setBrowserOrTabActiveTimestamp(new Date());
  }, 15000);
}

signin() {
  // ...
  this.setBrowserOrTabActiveTimestamp(new Date());
}

setBrowserOrTabActiveTimestamp(timeStamp: Date) {
  localStorage.setItem(
    'browserOrTabActiveSessionTimestamp',
    `${timeStamp.getTime()}`
  );
}

wasBrowserOrTabClosedAfterSignin(): boolean {
  const value = localStorage.getItem('browserOrTabActiveSessionTimestamp');

  const lastTrackedTimeStampWhenAppWasAlive = value
    ? new Date(Number(value))
    : null;
  const currentTimestamp = new Date();
  const differenceInSec = moment(currentTimestamp).diff(
    moment(lastTrackedTimeStampWhenAppWasAlive),
    'seconds'
  );

  // if difference between current timestamp and last tracked timestamp when app was alive
  // is more than 15sec (if user close browser or all opened *your app* tabs more than 15sec ago)
  return !!lastTrackedTimeStampWhenAppWasAlive && differenceInSec > 15;
}

工作原理: 如果用户关闭浏览器或关闭所有打开的您的应用程序选项卡,则在15秒超时后将触发注销。

  • 它可以与多个窗口一起使用
  • 服务器上没有额外的负载
  • F5 / 刷新没有问题

浏览器限制是我们需要15秒超时注销的原因。由于浏览器无法区分这些情况:浏览器关闭、选项卡关闭和选项卡刷新。浏览器将所有这些操作视为相同的操作。因此,15秒超时就像一个解决方法,只捕获浏览器关闭或关闭所有打开的您的应用程序选项卡(并跳过刷新/F5)。


看起来不错,但你在这里遇到的问题是必须重新打开页面才能请求注销。我会在后端添加这种代码,并检查如果后端没有从用户界面收到会话仍然存在的通知,则进行注销。 - Ofir Hadad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接