我有一个要求,如果用户闲置一段时间我必须注销用户。 我正在使用ng-idle 0.3.2。
如果在浏览器中打开了多个标签/窗口,我会遇到问题。如果我正在使用选项卡,并且在我正在处理的活动选项卡上登录时未登录的选项卡仍然已登录,因为它处于活动状态。
如何在我处理其他类似标签时阻止从非活动标签退出?
答案 0 :(得分:5)
使用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);
}
}
})
将指令属性添加到body标签,以确保检测到页面中的所有鼠标和键盘事件:
<body ng-app="myApp" idle>
Open up and run this Plunk以及每个标签的控制台。将鼠标光标移动到正文内容上,并观察记录到两个控制台的事件。
答案 1 :(得分:2)
我还没有使用过ngIdle,但通常你需要在这些情况下与服务器通信。即在$ keepalive事件中,向服务器发送请求以存储会话中的最后活动时间。在$ idleWarn中,向服务器发送请求以获取最新的活动时间戳,如果用户在其他选项卡中处于活动状态,那么您将获得最近的时间戳,因此您可以停止超时过程并发送保持活动。