【问题标题】:how to keep session alive on Mousemove or Keydown events using Timeout-dialog JS?如何使用 Timeout-dialog JS 在 Mousemove 或 Keydown 事件上保持会话活动?
【发布时间】:2017-05-18 07:31:05
【问题描述】:

我在我的应用程序中使用 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 来重置会话?

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

【问题讨论】:

    标签: javascript jquery timeout-dialog.js


    【解决方案1】:

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

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

    如果你只想让你的后端会话保持活跃,你可以像这样调用你的 keep-alive url:

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

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

    【讨论】:

    • 约翰史密斯感谢您的回复。有什么方法可以让我调用 keep_alive_url 以便让我的会话保持活动状态。听起来效率高吗?
    • 我已经编辑了我的答案,尝试使用这种方法
    • 这里面的_.throttle是什么?
    • Throttle 将确保 keep-alive 只能每 1000 毫秒调用一次。因此,您不会在每个鼠标移动事件(将是数百个)上都调用 keep-alive。
    【解决方案2】:

    我在检查一些浏览器对 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 响应,同时提供一个简单的检查以在需要时重定向/重新加载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 2012-04-10
      • 1970-01-01
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多