0

我在我的应用程序中使用 timeout-dialog.JS 在 5 分钟后过期非活动用户的会话。但是我有输入网格,其中用户可以添加多条记录,然后在添加假设说 10 条记录后,他进行了 SAVE,但他花了 5 多分钟才输入所有这些详细信息,以及他何时进行 SAVE 或当他说是时让我登录到超时对话框弹出屏幕重新加载,他丢失了所有数据。

我想要的是,如果他移动鼠标或按键,会话应该被重置。

为此,我尝试在布局页面中添加 mousemove 和 keydown 事件,如下所示:

     <script>
    $(function () {
        var fnTimeOut = function () {
            $.timeoutDialog.setupDialogTimer({
                timeout: 300,
                countdown: 60,
                logout_redirect_url: '@Url.Action("LogOff", "Account")',
                keep_alive_url: '@Url.Action("Keepalive", "Account")'
            });
        };
        fnTimeOut();

        $(this).mousemove(function () {
            $.timeoutDialog.setupDialogTimer({
                timeout: 300,
                countdown: 60,
                logout_redirect_url: '@Url.Action("LogOff", "Account")',
                keep_alive_url: '@Url.Action("Keepalive", "Account")'
            });             
        });

        $(this).keydown(function () {
            $.timeoutDialog.setupDialogTimer({
                timeout: 300,
                countdown: 60,
                logout_redirect_url: '@Url.Action("LogOff", "Account")',
                keep_alive_url: '@Url.Action("Keepalive", "Account")'
            });          
        });
    });
</script>

但这给了我警报,说页面对 KILL 或 WAIT 选项没有响应。

那么有什么方法可以在 mousemove 和 keydown 事件上使用 timeout-dialog JS 进行会话重置?

任何帮助将不胜感激。谢谢。

4

2 回答 2

0

像这样的原始mousemove事件侦听器对于您的目的来说太过分了,因为它每秒可以发出数百个事件,如果您正在执行更繁重的操作,这肯定会杀死您的应用程序。我可以看到你可以做两件事:

  • 限制事件,因此它们每 N 秒只执行一次 -> 参见Throttle
  • 想办法只重置 timeout-dialog 的内部计时器。查看源代码,看看 API 中是否没有任何内容可以执行此操作,而不是每次都设置一个全新的对话框(我怀疑这效率不高)。如果您需要任何进一步的帮助,请告诉我。

如果您只想保持后端会话处于活动状态,则可以像这样调用保持活动的 URL:

var callKeepAlive = _.throttle(function () {
  $.get( "<YOUR KEEP-ALIVE URL>", function( data ) {
    console.log('keep-alive called')
  });
}, 1000);

然后在你的 mousemove / keyup 事件监听器中,执行callKeepAlive()

于 2017-05-18T07:52:49.977 回答
-1

我在检查 XMLHttp 和随机浏览器线程的浏览器兼容性时遇到了这个问题。我想我会给出我想出的工作示例,因为我很快就需要类似的东西,并且认为这个问题可以用一个更大的示例来解决。

底部的代码非常少

请原谅我这有点混乱,这是一个原始的例子。

<?php
    // Do not forget session start if copying into your own code..
    if (isset($_GET['keepalive'])) {
        header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");
        header('Content-Type: application/json');
        $boolStatusOfSession = TRUE;        // Something like: $boolStatusOfSession = (isset($_SESSION['MyTokenWhenSignedIn']) ? TRUE : FALSE);
        echo json_encode(array('status'=>$boolStatusOfSession));
        exit;
    }
?>
<html>
    <head></head>
    <body>
        <p>This script will throttle the mouse movement event to a rate of once per second max and perform a keep alive request to the same page along with a json response of the session status</p>
        <p id="debugbox"><b>Server Keep Alive: </b>please wait for the timer (10 seconds)</p>
        <p id="debugbox2"></p>

        <script>
            var elmDebug = document.getElementById('debugbox');
            var elmDebug2 = document.getElementById('debugbox2');
            var idleStart = Math.floor(Date.now() / 1000);

            function keepAlivePoster() {
                objHttp = new XMLHttpRequest();
                objHttp.onreadystatechange = function() {
                    var strDebug = "<b>Server Keep Alive: </b> ";
                    if (objHttp.readyState == XMLHttpRequest.DONE) {
                        idleStart = Math.floor(Date.now() / 1000);  
                        objResp = JSON.parse(objHttp.responseText);
                        if (objResp.hasOwnProperty('status') && objResp.status == true) {
                            // DO STUFF HERE WHEN SIGNED IN (Or do nothing at all)
                            strDebug += "Signed In, ";
                        } else {
                            // DO STUFF HERE WHEN SIGNED OUT (A window reload if your page can handle the session change)
                            strDebug += "Signed Out, "; // Or does not exist / error.. best to use a int status
                        }
                    }
                    elmDebug.innerHTML = strDebug + "Updated at " + Math.floor(Date.now() / 1000);
                    elmDebug2.innerHTML = '<b>Mouse Move Event: </b> Idle timer reset to ' + idleStart;
                }
                objHttp.open('GET', '?keepalive');
                objHttp.send(null);
            };


            function throttleController (callback, limit) {     // TAKEN FROM: https://jsfiddle.net/jonathansampson/m7G64/
                var wait = false;                  // Initially, we're not waiting
                elmDebug2.innerHTML = '<b>Mouse Move Event: </b> Idle timer reset to ' + idleStart;
                return function () {               // We return a throttled function
                    if (!wait) {                   // If we're not waiting
                        callback.call();           // Execute users function
                        wait = true;               // Prevent future invocations 
                        setTimeout(function () {wait = false;}, limit); // After a period of time, allow future invocations again
                    }
                }
            }           
            window.addEventListener("mousemove", throttleController(keepAlivePoster, 10000));       // Allow "idleCallback" to run at most 1 time every 10 seconds

        </script>
    </body>
</html>

当然,您可以删除一些代码(调试等,因此是一个简单的基本脚本示例)

最小代码

function keepAlivePoster() {
    objHttp = new XMLHttpRequest();
    objHttp.open('GET', '?keepalive');
    objHttp.send(null);
};
function throttleController (callback, limit) {     // TAKEN FROM: https://jsfiddle.net/jonathansampson/m7G64/
    var wait = false;  return function () {              
        if (!wait) { callback.call();  wait = true; setTimeout(function () {wait = false;}, limit); }
    }
}           
window.addEventListener("mousemove", throttleController(keepAlivePoster, 10000));

最后一行您要复制的任何其他事件,当您使用多个事件时,您还希望在更高的范围/全局上设置等待变量。

为什么php状态/代码

那么首先这将在另一个文件中,该文件在 html 生成之前就包含在内。但理想情况下,您希望 GET 请求尽可能小,并带有一些规则等等。所以我禁用了该功能要缓存的页面和 json 响应可以很容易地被浏览器使用,同时提供一个简单的检查来重定向/重新加载(如果需要)。

于 2017-08-23T10:23:28.743 回答