JavaScript函数返回用户会话的负数秒数?

时间:2018-03-13 18:48:53

标签: javascript jquery session twitter-bootstrap-3 timer

我尝试创建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秒,但不会显示模态会话将结束。我不确定我的变量是否没有覆盖以前的值或我的代码中的其他错误。

1 个答案:

答案 0 :(得分:1)

我发现所有脚本都比需要的更复杂,并决定展示一个简化的解决方案。

此版本只需在鼠标或键活动时重启计时器,如果在第一次设置超时内没有,则会显示警告信息并重新启动计时器,在第二次之后,它会显示已注销的消息并取消绑定鼠标/关键事件。

从这里你可以添加你自己的模态对话框,ping服务器等。

更新了&#34;时间戳&#34;变量,因此对服务器的调用不会经常发生。

Stack snippet

&#13;
&#13;
$(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;
&#13;
&#13;