【问题标题】:how to logout a user when browser closed浏览器关闭时如何注销用户
【发布时间】:2017-12-28 13:36:32
【问题描述】:

我想在用户关闭浏览器时注销他们。为此我做了研发,发现当我们关闭浏览器时会触发以下代码。

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

在这里,当我尝试关闭浏览器时,将触发此事件并让用户注销。但是这里的问题是,当页面被重定向时,这个事件也被触发了。

我想用这个功能让用户注销。但是出错了。请帮我做这个功能。

【问题讨论】:

  • 所以不是单页应用?那么如果你有 2window 打开和关闭一个窗口呢?你还想注销吗?
  • 是的,我的应用程序是 Web 应用程序,即使打开了两个选项卡,我也想执行注销
  • 处理$rootScope中的$destroy事件,因为您使用的是angularjs
  • @KoushikChatterjee 你能给我一个示例代码吗
  • 只需实现会话超时。您真的无法判断用户何时“离开”。

标签: javascript angularjs


【解决方案1】:

但是这里的问题是当页面被重定向时,这个事件也被触发了。

我猜这是您自己正在执行的重定向。如果是这种情况,您为什么不使用全局变量来区分您的重定向和客户的重定向?像这样的:

...
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...';
    }
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:
      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)。

      【讨论】:

      • 看起来不错,但是您遇到的问题是您必须再次打开该页面才能要求注销。我会在 BE 中添加这种代码,并检查如果 BE 没有从 UI 收到会话已激活的通知,那么它将执行注销。
      猜你喜欢
      • 2020-10-23
      • 2017-01-19
      • 2012-04-24
      • 1970-01-01
      • 2015-08-22
      • 2017-01-05
      • 2020-12-27
      • 1970-01-01
      相关资源
      最近更新 更多