如果在浏览器中打开了多个选项卡/窗口,则为ng-idle问题

A_J*_*A_J 6 angularjs ng-idle

我有一个要求,如果它闲置一段时间我必须注销用户.我正在使用ng-idle 0.3.2.

如果在浏览器中打开了多个选项卡/窗口,我会遇到问题.如果我正在使用选项卡,并且在我正在处理的活动选项卡上时未登录的选项卡仍然登录,因为它处于活动状态.

如何在我处理其他类似标签时阻止从非活动标签退出?

Mar*_*ine 6

摘要

使用localStorage在运行应用程序的任何选项卡中存储上次已知活动事件的时间戳.在正在运行的应用的每个实例中每隔几秒轮询一次该值.如果已更新,请重置ng-idle计时器以避免过早注销(或者在广播$ idleTimeout事件时设置的任何操作).

如何

创建一个指令来体现上述行为:

.directive('idle', function($idle, $timeout, $interval){
  return {
    restrict: 'A',
    link: function(scope, elem, attrs) {
      var timeout;
      var timestamp = localStorage.lastEventTime;

      // Watch for the events set in ng-idle's options
      // If any of them fire (considering 500ms debounce), update localStorage.lastEventTime with a current timestamp
      elem.on($idle._options().events, function(){
        if (timeout) { $timeout.cancel(timeout); }
        timeout = $timeout(function(){
          localStorage.setItem('lastEventTime', new Date().getTime());
        }, 500);
      });

      // Every 5s, poll localStorage.lastEventTime to see if its value is greater than the timestamp set for the last known event
      // If it is, reset the ng-idle timer and update the last known event timestamp to the value found in localStorage
      $interval(function() {
        if (localStorage.lastEventTime > timestamp) {
          $idle.watch();
          timestamp = localStorage.lastEventTime;
        } 
      }, 5000);
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

将directive属性添加到body标记以确保检测到页面中的所有鼠标和键盘事件:

<body ng-app="myApp" idle>
Run Code Online (Sandbox Code Playgroud)

演示

打开并在多个选项卡中运行此Plunk以及每个选项卡的控制台.将鼠标光标移动到正文内容上,并观察记录到两个控制台的事件.


Aid*_*din 2

我还没有使用过 ngIdle,但通常在这些情况下你需要与服务器通信。即在 $keepalive 事件中,向服务器发送请求以存储会话中的最后活动时间。在 $idleWarn 中,向服务器发送请求以获取最新的活动时间戳,如果用户在其他选项卡中处于活动状态,那么您将获得最近的时间戳,因此您可以停止超时过程并发送 keepalive。