【问题标题】:how to kill a application session when a browser window is closed?关闭浏览器窗口时如何终止应用程序会话?
【发布时间】:2009-09-03 06:47:54
【问题描述】:

我有问题。

我正在开发一个聊天应用程序。如果用户在未注销的情况下关闭浏览器窗口,我想终止会话。我使用了 'beforeunload' 函数,但它也会在触发回发事件时触发,所以它对我不利。

如果有人对此有任何想法,请提供帮助。

【问题讨论】:

  • 你可以试试onunload。但坏主意。它在执行 AJAX 调用时几乎会挂起浏览器。最好的办法是检查用户的最后一次活动是否大于 30-60 秒,然后将他视为离线。

标签: javascript session


【解决方案1】:

如果您使用轮询来获取聊天数据,如果您在给定时间内没有收到来自客户端的轮询请求,则应该终止会话。

客户:

setInterval (pollData, 10000); /* poll for new data each 10 seconds */

服务器:

if (clientX.LastPollTime is over 30 seconds ago) {
    clientX.killSession();
}

【讨论】:

  • 如果我的聊天会话因为 30 秒不活动而被终止 - 我会不高兴。这是一种解决方法,而不是解决方案。
  • arnis:代码将在您打开时在浏览器中运行而无需您执行任何操作。这是一个解决方案。
  • 啊——别管我了。这个想法是将聊天客户端的“心跳”发送到服务器,对吗?
  • 对 - 信息轮询(即聊天消息)充当心跳
【解决方案2】:

我建议你使用 Alexanders 方法,但在大多数情况下,单独设置间隔时间并不能解决这个问题。因为用户可能闲置了一段时间,可能超过了超时时间。

为了避免这种情况,您需要在此基础上再添加一个条件。

  • 如果用户在超时期间处于空闲状态,则只需向服务器发出 AJAX 请求并将客户端状态更新为空闲。

  • 如果用户闲置一段时间,这将避免注销会话。

  • 并且您可以终止会话如果服务器在指定时间内没有收到客户端的任何响应并且状态未更新为空闲(在浏览器关闭或任何应用程序挂起期间)。

【讨论】:

    【解决方案3】:

    是的,亲爱的,这很好,但是第二件事,正如您指定的那样,该服务器没有收到任何响应,在我的代码服务器中,它只检查应用程序会话,它会找到它,所以它会工作。我想要的是,如果用户没有注销然后页面被杀死,然后我们如何从客户端调用任何 ajax 或 xmlhttp 请求以将应用程序会话设置为脱机。

    所以请大家告诉我一些事情,这是唯一不顺利的事情。感谢您的回复。

    【讨论】:

    • 如果它是一个聊天应用程序,我们有两方。两者都可以充当侦听器和接收器..两者都具有相同的功能。两者都在轮询服务器以获取响应。您不能从死掉的浏览器发出 AJAX 请求。但如果我没记错的话,对方仍然在线。他仍然轮询服务器。并且您可以验证其他用户是否仍然在线......有什么问题......??
    • okey,查看用户何时登录,我将 application(key)="1" 设置为在线。现在,如果用户单击注销,另一端服务器会定期检查应用程序会话,那么它应该是 application(key)='0';并让用户关闭窗口然后我如何更改此会话的值。
    • @Abhisheks.net:不要将 cmets 添加为“答案”。更新/编辑您的问题。
    【解决方案4】:

    正如你所说,当用户单击链接或刷新页面时会触发事件 window.onbeforeunload,因此即使结束会话也不好。

    但是,您可以在页面上放置一个 JavaScript 全局变量来识别不应触发注销的操作(例如,通过使用来自 onbeforeonload 的 AJAX 调用)。

    下面的脚本依赖于 JQuery

    /*
    * autoLogoff.js
    *
    * Every valid navigation (form submit, click on links) should
    * set this variable to true.
    *
    * If it is left to false the page will try to invalidate the
    * session via an AJAX call
    */
    var validNavigation = false;
    
    /*
    * Invokes the servlet /endSession to invalidate the session.
    * No HTML output is returned
    */
    function endSession() {
       $.get("<whatever url will end your session>");
    }
    
    function wireUpEvents() {
    
      /*
      * For a list of events that triggers onbeforeunload on IE
      * check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
      */
      window.onbeforeunload = function() {
          if (!validNavigation) {
             endSession();
          }
      }
    
      // Attach the event click for all links in the page
      $("a").bind("click", function() {
         validNavigation = true;
      });
    
      // Attach the event submit for all forms in the page
      $("form").bind("submit", function() {
         validNavigation = true;
      });
    
    }
    
    // Wire up the events as soon as the DOM tree is ready
    $(document).ready(function() {
        wireUpEvents();  
    });
    

    此脚本可能包含在所有页面中

    <script type="text/javascript" src="js/autoLogoff.js"></script>
    

    让我们看一下这段代码:

      var validNavigation = false;
    
      window.onbeforeunload = function() {
          if (!validNavigation) {
             endSession();
          }
      }
    
      // Attach the event click for all links in the page
      $("a").bind("click", function() {
         validNavigation = true;
      });
    
      // Attach the event submit for all forms in the page
      $("form").bind("submit", function() {
         validNavigation = true;
      });
    

    全局变量是在页面级别定义的。如果此变量未设置为 true,则事件 windows.onbeforeonload 将终止会话。

    一个事件处理程序附加到页面中的每个链接和表单以将此变量设置为 true,从而防止在用户只是提交表单或单击链接时终止会话。

    function endSession() {
       $.get("<whatever url will end your session>");
    }
    

    如果用户关闭浏览器/选项卡或导航离开,会话将终止。在这种情况下,全局变量未设置为 true,脚本将对您要结束会话的任何 URL 进行 AJAX 调用

    此解决方案与服务器端技术无关。它没有经过详尽的测试,但在我的测试中似乎运行良好

    PS:我已经在this question 发布了这个答案。我不确定是否应该回答多个相似的问题或发布参考?

    【讨论】:

      【解决方案5】:

      如果您可以控制 sessionID cookie,只需将其生命周期设置为 0,这会使会话在浏览器关闭时终止。可以通过服务器端存储会话中最后一次看到的时间并检查来控制打开窗口上会话的生命周期

      if(isset($_COOKIE[session_name()])) {
          setcookie(session_name(), $_COOKIE[session_name()], 0, "/"); // die @ browser close
      }
      if(isset($_SESSION['last_time'])){
          if( ( time() - $_SESSION['last_time'] ) > 300 ){ // 5 minutes timeout
              // here kill session;
          }
      }
      $_SESSION['last_time'] = time();
      

      在客户端,您可以使用 Daniel Melo 的答案。我正在使用它,只需做一点小改动:

      function endSession() {
         // $.get("<whatever url will end your session>");
         // kill the session id
         document.cookie = 'MYOWNSESSID=; path=/';
      }
      

      唯一悬而未决的问题是我还不能将事件连接到输入类型[按钮],我已经使用原始代码完成了它,但一切正常。

      【讨论】:

        猜你喜欢
        • 2015-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-24
        • 1970-01-01
        • 1970-01-01
        • 2010-12-27
        • 1970-01-01
        相关资源
        最近更新 更多