如何使用ajax请求更改setTimeout()计数器?

时间:2014-10-06 21:14:13

标签: javascript php jquery ajax session

我写了一个小的jQuery代码,如果页面未刷新1800秒,将显示一个对话框。在会话自动结束之前,该对话框具有倒计时。如果用户点击"是,继续工作"然后计数器重置,对话框消失。否则,用户将被转移到注销页面。

我在这里遇到的问题是当用户打开新浏览器标签并继续处理新标签页时。然后旧标签将变为空闲" 1800秒后没有刷新"所以他们放松了所有的会话并退出了。

我创建了一个PHP页面,它将通过使用$_SESSION信息检查数据库中的时间来返回剩余的秒数。但我不确定如何在对话框打开时重置计数器。

我不知道如何修改我的代码以检查显示对话框之前剩余的实际秒数。

这是我的代码

<!-- This script will alert a user before forcing to logout -->
<script type="text/javascript">
    var timer;
    var closeDialogAfter = 180;  //The default counter value
    var idleTimeOutLimit = 1800 - closeDialogAfter; //Display the dialog after @idleTimeOutLimit seconds of idle time
    var signOutScript = '/index.php?action=logout';   //logout url
    var keepAliveScript = '/ajax/handler-keep-me-alive.php';  //php page to handle ajax request to keep the session alive
    var dialogCountdown = '#dialog-countdown';  // the lable that is used to display the counter
    var idleTimeout= '#idleTimeout';  //the div that is used for the dialog 

    $(function(){

        //start the idle time out counter
        startTimeoutCounter();

        $( idleTimeout ).dialog({
            resizable: false,
            autoOpen: false,
            width: 400,
            open: function(){
                updateTimeoutCounter();
            },
            buttons: {
                "Yes, Keep working": function(e) {
                    $.ajax({    
                        url: keepAliveScript,       
                        success: function(data) {
                            startTimeoutCounter();
                            $( idleTimeout ).dialog("close");
                        }
                    });
                },
                "No, End Session": function(e){
                    forceLogOut();
                    $(this).dialog('close');                
                }
            }
        }); 
    });


    function startTimeoutCounter(){
        timer = closeDialogAfter;
        $(dialogCountdown).text(timer);

        setTimeout(function(){
            $( idleTimeout ).dialog("open");
        }, idleTimeOutLimit * 1000);
    }

    function updateTimeoutCounter(){

        if(  $( idleTimeout ).dialog( "isOpen" )){

            setTimeout(function(){
                timer = timer -1;
                $(dialogCountdown).text(timer);
                (timer < 2) ? forceLogOut() :   updateTimeoutCounter();
            }, 1000);
        } else 
            $(dialogCountdown).text(closeDialogAfter)
    }   

    function forceLogOut(){
        window.location = signOutScript;
    }

</script>

2 个答案:

答案 0 :(得分:0)

在你的脚本php中你需要只返回剩余的秒数
你的javascript需要从ajax请求开始到php页面。

<script type="text/javascript">
    $.get("timeleft.php",function(data){
        var timer;
        var closeDialogAfter = parseInt(data);  //<-- what i changed
        var idleTimeOutLimit = 1800 - closeDialogAfter; //Display the dialog after @idleTimeOutLimit seconds of idle time
        var signOutScript = '/index.php?action=logout';   //logout url
        var keepAliveScript = '/ajax/handler-keep-me-alive.php';  //php page to handle ajax request to keep the session alive
        var dialogCountdown = '#dialog-countdown';  // the lable that is used to display the counter
        var idleTimeout= '#idleTimeout';  //the div that is used for the dialog 

        $(function(){

            //start the idle time out counter
            startTimeoutCounter();

            $( idleTimeout ).dialog({
                resizable: false,
                autoOpen: false,
                width: 400,
                open: function(){
                    updateTimeoutCounter();
                },
                buttons: {
                    "Yes, Keep working": function(e) {
                        $.ajax({    
                            url: keepAliveScript,       
                            success: function(data) {
                                startTimeoutCounter();
                                $( idleTimeout ).dialog("close");
                            }
                        });
                    },
                    "No, End Session": function(e){
                        forceLogOut();
                        $(this).dialog('close');                
                    }
                }
            }); 
        });


        function startTimeoutCounter(){
            timer = closeDialogAfter;
            $(dialogCountdown).text(timer);

            setTimeout(function(){
                $( idleTimeout ).dialog("open");
            }, idleTimeOutLimit * 1000);
        }

        function updateTimeoutCounter(){

            if(  $( idleTimeout ).dialog( "isOpen" )){

                setTimeout(function(){
                    timer = timer -1;
                    $(dialogCountdown).text(timer);
                    (timer < 2) ? forceLogOut() :   updateTimeoutCounter();
                }, 1000);
            } else 
                $(dialogCountdown).text(closeDialogAfter)
        }   

        function forceLogOut(){
            window.location = signOutScript;
        }
    });
</script>

答案 1 :(得分:0)

正如您所说,您需要检查对话框打开前的时间。当页面加载时,您可以假设整整1800秒。

我想你可能想要这样的东西(参见下面的代码和注释中的注释)。

<!-- This script will alert a user before forcing to logout -->
<script type="text/javascript">
$(function() {
    var timer;
    var closeDialogAfter = 180;  //The default counter value
    var idleTimeOutLimit = <?php echo $sessionTimeoutValue ?>; //Time after which 
    var signOutScript = '/index.php?action=logout';   //logout url
    var keepAliveScript = '/ajax/handler-keep-me-alive.php';  //php page to handle ajax request to keep the session alive
    var getSessionTimeScript = '/ajax/get_session_time.php';  //php page to handle ajax request for the remaining session length
    var $dialogCountdown = $('#dialog-countdown');  //the container used to display the counter
    var $idleTimeout = $('#idleTimeout'); //the div that is used for the dialog

    function startTimeoutCounter(t) {
        t = Math.max(closeDialogAfter, parseInt(t, 10) || 0);
        $idleTimeout.dialog("close");
        setTimeout(getSessionTimeRemaining, (t - closeDialogAfter) * 1000);
    }
    function updateTimeoutCounter() {
        if($idleTimeout.dialog("isOpen")) {
            setTimeout(function() {
                timer = timer - 1;
                $dialogCountdown.text(timer);
                if(timer < 2) {
                    // Here, forceLogOut() can't be assumed because 
                    // the session may have been kept alive from another tab.
                    // Therefore, call getSessionTimeRemaining().
                    getSessionTimeRemaining();
                } else {
                    updateTimeoutCounter();
                }
            }, 1000);
        } else {
            $dialogCountdown.text(closeDialogAfter);
        }
    }   
    function forceLogOut() {
        $idleTimeout.dialog("close");
        window.location = signOutScript;
    }
    function getSessionTimeRemaining() {
        $.get(getSessionTimeScript).then(function(t) {
            t = parseInt(t, 10) || 0;
            if(t <= 0) {
                forceLogOut();
            } else if(t <= closeDialogAfter) {
                timer = closeDialogAfter;
                $dialogCountdown.text(timer);
                $idleTimeout.dialog("open");
            } else {
                startTimeoutCounter(t);
            }
        }, function(error) {
            // Something went wrong, safest action is logout
            // This will only happen under abnormal circumstances
            console.error(error);
            forceLogOut();
        });
    };
    function keepAlive() {
        $.get(keepAliveScript).then(startTimeoutCounter);
    }

    $idleTimeout.dialog({
        resizable: false,
        autoOpen: false,
        width: 400,
        open: updateTimeoutCounter,
        buttons: {
            "Yes, Keep working": keepAlive,
            "No, End Session": forceLogOut
        }
    });
    // On page load, the session should have been reset by the script that serves this page,
    // therefore no need to call keepAlive(), though that would do the same job.
    startTimeoutCounter(idleTimeOutLimit);
});
</script>

你会看到主要的结构差异是$(function() {...})现在包裹了所有东西。这样就无需使用全局名称空间。

新功能getSessionTimeRemaining()及其服务器端对应getSessionTimeScript是允许多个选项卡响应会话超时的核心。

两个脚本keepAliveScriptgetSessionTimeScript(可以是具有不同查询字符串的相同脚本)必须以秒为单位返回时间tt被认为是一个String,它被转换为parseInt()的数字。您可能希望返回的时间略小于剩余的实际会话时间,从而允许短暂的“宽限期”。你不想要的是给用户希望在会话已经过期时保持会话活着。

函数startTimeoutCounter(t)现在接受以秒为单位的时间,因此它可以在任何剩余时间内工作,这不一定是完整的1800秒,具体取决于调用是否来自keepAlive()(异步)或getSessionTimeRemaining()

新功能keepAlive()允许整洁的“按钮”定义。

所有完全未经测试。你可能仍然需要修补它。