我尝试创建JS功能,该功能应跟踪用户活动,并在用户处于非活动状态时显示警告模式框。功能将在页面加载时开始。一些变量是全局的,我使用它们来设置会话分钟并在屏幕上保持用户活动。简单地说,我计算用户会话的时间并减去警告显示之前的秒数。如果用户在页面主体上处于活动状态,我将JS日期对象保存在全局变量中。一旦计时器降至0,我将重置时间或触发功能,该功能将注销用户并重定向到登录页面。我的代码中发生了一个问题,如果用户扩展了会话(只需单击模式框中的继续按钮),计时器应该重新启动并且该部分正常工作。计时器重启计数和一旦达到0警告应再次显示,而不是我的expierIn
变量返回负数。我将任何数字等于或小于零设置为0.所以我的会话会自动结束。这是错误的,我不确定为什么我的数学第二次返回负数。这是我的代码的工作示例。我没有包含Ajax调用,它应该向服务器发送ping以使服务器端会话保持活动状态。
$(document).ready(function(){
TimeOut(); // Call session timeout function.
});
/*** Start: Session Timeout Handling(The following functions are part of session handling). ***/
var sessionMinutes = 4; // Session time in minutes.
var dmSessionBox; // Session timeout warning box
var lastActivity = null; // keeps track of user last activity
var timeout = null; // keeps timeout value
var secondsToShowDialog = 120; // number of seconds until modal shows on the screen
var dialogShowing = false; // flag to show/hide modal
var nextPoll = false; // flag to set next timeout
var lastHist = new Date(); // first time user logged to the system.
log('lastHit: '+lastHist.toLocaleTimeString());
function TimeOut() {
if (sessionMinutes) {
dmSessionBox = $('<div id="sessiontimeoutwarning" class="modal fade" role="dialog"><div class="modal-dialog modal-lg"><div class="modal-content"> <div class="modal-header"><h2 class="modal-title warning"><span class="glyphicon glyphicon-warning-sign"></span>Your session is about to expire</h2></div> <div class="modal-body"><div class="alert alert-warning warning"> <strong>Warning!</strong>Click the Continue button to extend your session. </div></div><div class="modal-footer"><button type="button" id="continueButton" class="btn btn-primary" data-dismiss="modal">Continue</button</div>/div>/div>/div>');
$(document.body).append(dmSessionBox);
$('body').on('mousedown keydown', function(event) {
lastActivity = new Date();
});
var sessionSeconds = sessionMinutes * 60; // Convert session minutes in seconds.
log("Init - session is set to expire in " + sessionSeconds + " seconds at " + new Date(new Date().getTime() + (sessionSeconds*1000)).toLocaleTimeString());
receiveUpdatedTimeRemaining(sessionSeconds);
}
}
function receiveUpdatedTimeRemaining(timeout) {
if (nextPoll)
clearTimeout(nextPoll);
var wakeUpMillis;
if (timeout <= (secondsToShowDialog)) {
if (!dialogShowing)
lastActivity !== null ? getTimeout() : showTimeoutDialog(true);
wakeUpMillis = 30 * 1000;
}else{
showTimeoutDialog(false);
dialogShowing = false;
wakeUpMillis = (timeout * 1000) - (secondsToShowDialog * 1000);
}
log("receiveUpdatedTimeRemaining - Wake up in " + parseInt(wakeUpMillis/1000) + " for new timeout");
nextPoll = setTimeout(getTimeout, wakeUpMillis);
}
function getTimeout() {
clearTimeout(nextPoll);
var currentTime = new Date().getTime(),
lastClick = lastActivity !== null ? lastActivity.getTime() : lastHist.getTime(),
secondsPassed = (currentTime - lastClick) / 1000, // Elapsed number of seconds since last user activity.
totalSeconds = sessionMinutes * 60, // Total number of seconds for this session
expierIn = totalSeconds - secondsPassed;
log('expierIn: '+expierIn);
timeout = expierIn <= 0 ? 0 : expierIn; // Set time in timeout variable
timeout == 0 ? showTimeoutErrorDialog() : receiveUpdatedTimeRemaining(timeout);
lastActivity = null; // Reset lastActivity
}
function showTimeoutDialog(showIt) {
dmSessionBox.find('#continueButton').on('click', function() {
lastActivity = new Date();
getTimeout();
});
showIt ? $('#sessiontimeoutwarning').modal('show') : $('#sessiontimeoutwarning').modal('hide');
dialogShowing = true;
}
function showTimeoutErrorDialog() {
$('#sessiontimeoutwarning').modal('hide'); // Close modal box
log('Session timed out.')
}
function log(msg){
if (window.console && console.log)
console.log(new Date().toLocaleTimeString() + " :: " + msg);
}
/*** End: Session timeout handling. ***/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<html>
<head>
<title>Session Timeout Test</title>
</head>
<body>
<div>My App</div>
</body>
</html>
警告显示后,我点击继续会话将再延长240秒,并且警告的唤醒呼叫设置为120秒,但不会显示模态会话将结束。我不确定我的变量是否没有覆盖以前的值或我的代码中的其他错误。
答案 0 :(得分:1)
我发现所有脚本都比需要的更复杂,并决定展示一个简化的解决方案。
此版本只需在鼠标或键活动时重启计时器,如果在第一次设置超时内没有,则会显示警告信息并重新启动计时器,在第二次之后,它会显示已注销的消息并取消绑定鼠标/关键事件。
从这里你可以添加你自己的模态对话框,ping服务器等。
更新了&#34;时间戳&#34;变量,因此对服务器的调用不会经常发生。
Stack snippet
$(document).ready(function(){
TimeOut();
$('body').on('mousedown keydown', function(event) {
TimeOut();
});
});
var TimeOut = (function(t,ts) {
function startTimeOut() {
// clear any warnings etc.
document.body.innerHTML = 'My App<br>';
if (t) {
clearTimeout(t);
}
t = setTimeout(timedWarn, 5000);
// set a time stamp and check when to ping server
if (ts) {
var ct = new Date().getTime();
//call server every e.g. 12 sec. and reset time stamp
if ( (ct - ts) / 1000 > 12 ) {
// sendPing();
ts = new Date().getTime();
console.log('send ping');
}
} else {
ts = new Date().getTime();
}
}
function timedWarn() {
t = setTimeout(timedOut, 5000);
// show warn dialog
document.body.innerHTML += 'Because of inactivity you are about to be logged out.'
}
function timedOut() {
// logout, redirect
document.body.innerHTML = 'Logged out';
// unbind is not needed if a redirect is made
$('body').unbind('mousedown keydown');
}
return (function() {
startTimeOut();
});
})();
&#13;
body {
margin: 0;
height: 100vh;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<html>
<head>
<title>Session Timeout Test</title>
</head>
<body>
My App<br>
</body>
</html>
&#13;