【问题标题】:Warn the user before session timeout在会话超时之前警告用户
【发布时间】:2014-07-18 19:02:47
【问题描述】:

我在Spring MVCJSP 中实现了一个 Web 应用程序。
默认会话超时在web.xml 中定义为 30 分钟。

如果用户空闲 25 分钟,我需要向用户显示一个弹出窗口,其中包含 Your session is going to be end by 5 min, Please click OK to continue 的消息。

我们是否可以使用JavaScriptjquery 或任何其他方法来实现这一目标?

请提出建议。

【问题讨论】:

  • 你可以使用 websockets
  • @GovindSinghNagarkoti 如何使用 websockets?我找不到任何示例

标签: java javascript jquery session


【解决方案1】:

您可以使用以下插件 - Jtimeout jquery plugin 完美运行,也可配置。文档很清楚

【讨论】:

  • 请在您的回答中提供更详细的解释。强烈鼓励答案将其解决方案完全放在帖子本身中。这意味着不仅仅包含指向某些外部资源的链接。如果您包含的链接中断,您的答案将变得比无用更糟糕。也许写一个使用您链接的插件的小示例,或者至少突出显示您认为可以解决提问者问题的特定插件方法。
【解决方案2】:

为了在前端通知用户超时,您需要从后端传递此信息。为此,我使用https://www.javaworld.com/article/2073234/tracking-session-expiration-in-browser.html 中的信息作为基线。

在控制器的每个响应方法中,您需要包含包含会话超时时间以及当前服务器时间的 cookie。由于听起来您已经在 web.xml 中设置了会话超时,因此您可以将 cookie 添加到您的响应中,类似于:

@RequestMapping(value="/example", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public ResponseEntity<Object> getExample(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {
     addTimeoutCookies(servletRequest, servletResponse);

     //Do actual actions

     return new ResponseEntity<Object>(HttpStatus.OK)
}

private void addTimeoutCookies(HttpServletRequest servletRequest, HttpServletResponse servletResponse) {

    long currTime = System.currentTimeMillis();
    long expiryTime = currTime + servletRequest.getSession().getMaxInactiveInterval() * 1000;

    Cookie serverTimeCookie = new Cookie("serverTime", "" + currTime);
    serverTimeCookie.setPath("/");
    servletResponse.addCookie(serverTimeCookie);

    Cookie expiryCookie = new Cookie("sessionExpiry", "" + expiryTime);
    expiryCookie.setPath("/");
    servletResponse.addCookie(expiryCookie);
}

然后,在前端,您需要检索这些 cookie 的值并将它们与客户端当前时间进行比较,以确定何时通知用户即将到来的会话超时。这是一个简单的代码块,基于此处的其他答案和链接中的文章:

var currTimeCookieName = 'serverTime';
var expireTimeCookieName = 'sessionExpiry';
var offset;
var warningTime = 5 * 60 * 1000;
var timeoutWarningMessage = 'Your session is going to be end by 5 min, Please click OK to continue';

function getCookie(name)
{
    var name = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0; i<ca.length; i++)
    {
        var c = ca[i].trim();
        if (c.indexOf(name)==0) return c.substring(name.length,c.length);
    }
    return "";
}

var serverTime = getCookie(currTimeCookieName);
serverTime = serverTime==null ? null : Math.abs(serverTime);
var offset = (new Date()).getTime() - serverTime;

function getTimeToWarning() {
    var expireTime = getCookie(expireTimeCookieName);
    return expireTime + offset - currTime - warningTime;
}

function checkForTimeout() {
    var timeUntilWarning = getTimeToWarning();

    setTimeout(function(){
        if (getTimeToWarning() > 0) {
            checkForTimeout();
        } else {

            if(confirm(timeoutWarningMessage)) {
                //TODO do a backend call or other action to extend the session here

                setTimeout(function() {
                    checkForTimeout();
                }, 1 * 60 * 1000);
            }
        }
    }, timeUntilWarning);
}

checkForTimeout();

【讨论】:

    【解决方案3】:

    你可以像下面这样使用:我在像 header.jsp 这样的 jsp 页面中使用它。这对我来说可以。我正在使用 spring、jsp 和 jquery。

    javascript:

    <code>
    <script type="text/javascript">
        //var recall = true;
        function loadDialog() { 
                var sessionAlive = ${pageContext.session.maxInactiveInterval};          
                var notifyBefore = 30; // Give client 15 seconds to choose.
                setTimeout(function() {       
                    $(function() {
                        $( "#dialog" ).dialog({
                            autoOpen: true,
                            maxWidth:400,
                            maxHeight: 200,
                            width: 400,
                            height: 200,
                            modal: true,
                            open: function(event, ui) {
                                setTimeout(function(){
                                    $('#dialog').dialog('close'); 
                                }, notifyBefore * 1000);
                            },
                            buttons: {
                            "Yes": function() {  
                                 $.get("/about", function(data,status){
                                   // alert("Data: " + data + "\nStatus: " + status);
                                  });                             
                                $('#dialog').dialog("close");
                                loadDialog();
                            },
                            "No": function() {  
                                $('#dialog').dialog("close");
                            }
                           },
                           close: function() {}
                        });
                      });
                }, (sessionAlive - notifyBefore) * 1000);
        };
    
        loadDialog(); 
    </script>
    

    HTML 分区:

    <div id="dialog" title="Session Timeout Info" style="display:none">
      <p>
        Your session will be timeout within 30 seconds. Do you want to continue session?  
      </p>
    </div> 
    </code>
    

    【讨论】:

    • 这给出了这个错误:TypeError: $(...).dialog is not a function
    【解决方案4】:

    试试这个代码。希望它能解决你的问题。谢谢

    var cookieName = 'sessionMsg';
    var message = 'Your session is going to be end by 5 min, Please click OK to continue';
    
    function getCookie(name)
    {
        var name = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0; i<ca.length; i++)
        {
            var c = ca[i].trim();
            if (c.indexOf(name)==0) return c.substring(name.length,c.length);
        }
        return "";
    }
    
    function setSessionPrompt() {
        var timeout = getCookie(cookieName) - new Date().getTime();
        setTimeout(function(){
            if (new Date().getTime() < getCookie(cookieName)) {
                setSessionPrompt();
            } else {
                if(confirm(message)) {
                    // do your action here
                }
            }
        }, timeout);
    }
    
    setSessionPrompt();
    

    【讨论】:

      【解决方案5】:

      你知道吗 windows.setTimeout

      http://www.w3schools.com/jsref/met_win_settimeout.asp

      这是你需要的

      例如

      var resetTime_int;
      function resetTimer(){
          if(resetTime_int) window.clearTimeout(resetTime_int)
          resetTime_int=window.setTimeout(function (){
          if(prompt('Your session is going to be end by 5 min, Please click OK to continue'))     
          location.reload()
          }, 1000*60*25)
      }
      
      resetTimer()
      document.onmousemove=resetTimer
      document.onkeyup=resetTimer
      

      1000*60*25 = 25 分钟。

      【讨论】:

      • 他需要一种服务器端方法。只有在 idle 30 分钟后,用户才会注销。这将警告用户忽略这一事实。
      • 假设用户在 12:00 登录。他们与网络应用程序交互直到 12:05。用户应在 12:35 注销,从而在 12:30 收到警告。用你的方法,他们会在 12:25 收到警告。
      • 如果用户与 web 应用程序交互,服务器将不知道它。如果用户在做一些 ajax,你需要重置计时器。
      • 大多数时候,服务器会知道它,除非一切都完全是客户端,没有任何 AJAX。
      • 是的山姆..你是对的。我需要用户的非活动间隔时间。如果它达到 25 分钟,那么我只需要显示消息。使用 Amina 方法,它将在登录 25 分钟后显示消息。如果我错了,请纠正。
      【解决方案6】:

      您应该使用 WebSockets 将数据从 Web 应用程序发送到客户端浏览器。

      1) 计算服务器端的会话超时。 2) Websocket 会发送会话超时消息。

      【讨论】:

        【解决方案7】:

        您可以在每个请求上发送一个带有剩余时间(以毫秒为单位)的 cookie。然后您可以按照建议使用 setTimeout 但在执行超时功能时再次测试该值。如果值已更改,您可以重置超时。由于 cookie 是为整个域设置的,因此即使对于 ajax 或其他选项卡,它也始终是正确的。

        var cookieName = 'sessionMsg';
        var message = 'Your session is going to be end by 5 min, Please click OK to continue';
        
        function getCookie(name)
        {
            var name = name + "=";
            var ca = document.cookie.split(';');
            for(var i=0; i<ca.length; i++)
            {
                var c = ca[i].trim();
                if (c.indexOf(name)==0) return c.substring(name.length,c.length);
            }
            return "";
        }
        
        function setSessionPrompt() {
            var timeout = getCookie(cookieName) - new Date().getTime();
            setTimeout(function(){
                if (new Date().getTime() < getCookie(cookieName)) {
                    setSessionPrompt();
                } else {
                    if(confirm(message)) {
                        // do your action here
                    }
                }
            }, timeout);
        }
        
        setSessionPrompt();
        

        【讨论】:

          猜你喜欢
          • 2015-07-29
          • 1970-01-01
          • 2016-02-18
          • 2014-11-09
          • 1970-01-01
          • 2016-02-06
          • 2012-05-18
          • 1970-01-01
          • 2016-09-11
          相关资源
          最近更新 更多