代码之家  ›  专栏  ›  技术社区  ›  Abhishek

当浏览器窗口关闭时,如何终止应用程序会话?

  •  1
  • Abhishek  · 技术社区  · 17 年前

    我有问题。

    我正在研究一个聊天应用程序。如果用户关闭浏览器窗口而不注销,我想终止会话。我使用了“beforeunload”函数,但在触发回发事件时它也会激发,因此对我不好。

    如果有人知道,请帮忙。

    5 回复  |  直到 15 年前
        1
  •  7
  •   Alex Gyoshev    17 年前

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

    客户:

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

    服务器:

    if (clientX.LastPollTime is over 30 seconds ago) {
        clientX.killSession();
    }
    
        2
  •  1
  •   RameshVel    17 年前

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

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

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

    • 如果用户在某个时间内处于IDEL状态,这将避免注销会话。

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

        3
  •  1
  •   Abhishek    17 年前

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

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

        4
  •  1
  •   Community Mohan Dere    9 年前

    正如您所说,事件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调用。

    此解决方案是服务器端技术不可知论。它没有经过严格的测试,但在我的测试中似乎效果良好。

    附言:我已经把这个答案贴在 this question . 我不确定我应该回答多个类似的问题,还是发表一篇参考文章?

        5
  •  1
  •   Carlos Mora    15 年前

    如果您拥有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();
    

    在客户方,你可以使用丹尼尔·梅洛的答案。我用它换了一个零钱:

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

    唯一悬而未决的问题是,我还不能将事件连接到输入类型[按钮],我已经用原始代码完成了它,但所有的事情都可以工作。