关闭浏览器或选项卡时关闭/终止会话

时间:2009-12-17 13:54:17

标签: asp.net session

当有人关闭浏览器时,有人可以告诉我如何关闭/终止会话?我正在为我的asp.net web应用程序使用stateserver模式。 onbeforeunload方法不正确,因为当用户刷新页面时它会触发。

9 个答案:

答案 0 :(得分:29)

你做不到。 HTTP是一种无状态协议,因此您无法判断用户何时关闭了浏览器,或者他们只是坐在那里,打开浏览器窗口什么都不做。

这就是会话超时的原因 - 您可以尝试减少超时以便更快地关闭非活动会话,但这可能会导致合法用户提前超时。

答案 1 :(得分:7)

如上所述,浏览器不会让服务器知道它何时关闭。

但是,有一些方法可以实现接近这种行为。您可以放置​​一个小型AJAX脚本,定期更新服务器以确保浏览器处于打开状态。您应该将此配对与用户所做的操作激发的内容配对,这样您就可以将空闲会话以及已关闭的会话超时。

答案 2 :(得分:6)

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

http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx描述了触发window.onbeforeonload的所有情况。 (IE)

但是,您可以在页面上放置一个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调用

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

答案 3 :(得分:4)

对于浏览器关闭,您可以将以下代码放入web.config:

<system.web>
    <sessionState mode="InProc"></sessionState>
 </system.web>

它将在浏览器关闭时销毁您的会话,但它不适用于标签关闭。

答案 4 :(得分:3)

我这样做:

$(window).bind('unload', function () {
    if(event.clientY < 0) {  
        alert('Thank you for using this app.');
        endSession(); // here you can do what you want ...
    }  
    });
window.onbeforeunload = function () {
    $(window).unbind('unload');
    //If a string is returned, you automatically ask the 
    //user if he wants to logout or not...
    //return ''; //'beforeunload event'; 
    if (event.clientY < 0) {
        alert('Thank you for using this service.');
        endSession();
    }  
}  

答案 5 :(得分:3)

请参考以下步骤:

  1. 首先创建一个SessionClear.aspx页面并编写清除会话的代码
  2. 然后在您的页面或母版页中添加以下JavaScript代码:

    <script language="javascript" type="text/javascript">
        var isClose = false;
    
        //this code will handle the F5 or Ctrl+F5 key
        //need to handle more cases like ctrl+R whose codes are not listed here
        document.onkeydown = checkKeycode
        function checkKeycode(e) {
        var keycode;
        if (window.event)
        keycode = window.event.keyCode;
        else if (e)
        keycode = e.which;
        if(keycode == 116)
        {
        isClose = true;
        }
        }
        function somefunction()
        {
        isClose = true;
        }
    
        //<![CDATA[
    
            function bodyUnload() {
    
          if(!isClose)
          {
                  var request = GetRequest();
                  request.open("GET", "SessionClear.aspx", true);
                  request.send();
          }
            }
            function GetRequest() {
                var request = null;
                if (window.XMLHttpRequest) {
                    //incase of IE7,FF, Opera and Safari browser
                    request = new XMLHttpRequest();
                }
                else {
                    //for old browser like IE 6.x and IE 5.x
                    request = new ActiveXObject('MSXML2.XMLHTTP.3.0');
                }
                return request;
            } 
        //]]>
    </script>
    
  3. 在母版页的body标签中添加以下代码。

    <body onbeforeunload="bodyUnload();" onmousedown="somefunction()">
    

答案 6 :(得分:3)

目前不完美但最佳解决方案:

var spcKey = false;
var hover = true;
var contextMenu = false;

function spc(e) {
    return ((e.altKey || e.ctrlKey || e.keyCode == 91 || e.keyCode==87) && e.keyCode!=82 && e.keyCode!=116);
}

$(document).hover(function () {
    hover = true;
    contextMenu = false;
    spcKey = false;
}, function () {
    hover = false;
}).keydown(function (e) {
    if (spc(e) == false) {
        hover = true;
        spcKey = false;
    }
    else {
        spcKey = true;
    }
}).keyup(function (e) {
    if (spc(e)) {
        spcKey = false;
    }
}).contextmenu(function (e) {
    contextMenu = true;
}).click(function () {
    hover = true;
    contextMenu = false;
});

window.addEventListener('focus', function () {
    spcKey = false;
});
window.addEventListener('blur', function () {
    hover = false;
});

window.onbeforeunload = function (e) {
    if ((hover == false || spcKey == true) && contextMenu==false) {
        window.setTimeout(goToLoginPage, 100);
        $.ajax({
            url: "/Account/Logoff",
            type: 'post',
            data: $("#logoutForm").serialize(),
        });
        return "Oturumunuz kapatıldı.";
    }
    return;
};

function goToLoginPage() {
    hover = true;
    spcKey = false;
    contextMenu = false;
    location.href = "/Account/Login";
}

答案 7 :(得分:2)

当机器因电源故障意外关机时,无法终止会话变量。只有当用户长时间闲置或者正确注销时才可以使用。

答案 8 :(得分:1)

使用此:

 window.onbeforeunload = function () {
    if (!validNavigation) {
        endSession();
    }
}

jsfiddle

在浏览器或标签关闭时,阻止F5,表单提交,输入点击和关闭/终止会话,在ie8 +和现代浏览器中测试,享受!