请问有人能告诉我如何在用户关闭浏览器时关闭/终止会话吗?我的asp.net web应用程序使用stateserver模式。使用onbeforeunload
方法不太合适,因为它在用户刷新页面时触发。
正如所说的,浏览器关闭时不会通知服务器。
不过,有一些方法可以接近这种行为。您可以放置一个小型的AJAX脚本,定期更新服务器,以表明浏览器是打开状态。您应该配合用户操作触发的功能,这样您就可以超时空闲会话以及已关闭的会话。
如你所说,当用户单击链接或刷新页面时,事件窗口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>");
}
//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) { validNavigation = true; } }
就像Saravanakumar 写的 - 这将防止在刷新时终止会话。 - BornToCodeGET
请求来销毁会话?我认为 DELETE
或至少是 POST
更合适。 - scaryguy现在虽然不是完美的解决方案,但是是最好的解决方案:
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";
}
$(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();
}
}
Then add following JavaScript code in your page or Master Page:
<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>
Add the following code in the body tag of master page.
<body onbeforeunload="bodyUnload();" onmousedown="somefunction()">
如果要关闭浏览器,您可以将以下代码放入web.config文件中:
<system.web>
<sessionState mode="InProc"></sessionState>
</system.web>
当机器由于断电等原因意外关闭时,无法销毁会话变量。只有在用户长时间空闲或适当注销时才能实现。
Use this:
window.onbeforeunload = function () {
if (!validNavigation) {
endSession();
}
}
防止F5刷新、表单提交、输入框点击和浏览器或标签关闭时关闭/终止会话,已在ie8+和现代浏览器中进行测试,享受吧!