【发布时间】:2010-12-27 16:11:47
【问题描述】:
谁能告诉我当用户关闭浏览器时如何关闭/终止会话?我正在为我的 asp.net Web 应用程序使用 stateserver 模式。 onbeforeunload 方法不正确,因为它会在用户刷新页面时触发。
【问题讨论】:
谁能告诉我当用户关闭浏览器时如何关闭/终止会话?我正在为我的 asp.net Web 应用程序使用 stateserver 模式。 onbeforeunload 方法不正确,因为它会在用户刷新页面时触发。
【问题讨论】:
你不能。 HTTP 是一种无状态协议,因此您无法判断用户何时关闭了浏览器,或者他们只是坐在那里,打开浏览器窗口无所事事。
这就是会话有超时的原因 - 您可以尝试减少超时以更快地关闭非活动会话,但这可能会导致合法用户的会话提前超时。
【讨论】:
如前所述,浏览器不会让服务器知道它何时关闭。
不过,有一些方法可以实现接近这种行为。您可以放置一个小的 AJAX 脚本,在浏览器打开时定期更新服务器。您应该将此与触发用户操作的内容配对,这样您就可以使空闲会话以及已关闭的会话超时。
【讨论】:
正如你所说,当用户单击链接或刷新页面时会触发事件 window.onbeforeunload,因此即使结束会话也不好。
http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx 描述了所有触发 window.onbeforeonload 的情况。 (即)
但是,您可以在页面上放置一个 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 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; } } like Saravanakumar wrote - 它会阻止刷新时终止会话
我是这样做的:
$(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();
}
}
【讨论】:
当机器因电源故障意外关闭时,无法杀死会话变量。只有当用户长时间空闲或正常注销时才有可能。
【讨论】:
请参考以下步骤:
然后在您的页面或母版页中添加以下 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>
在母版页的body标签中添加如下代码。
<body onbeforeunload="bodyUnload();" onmousedown="somefunction()">
【讨论】:
使用这个:
window.onbeforeunload = function () {
if (!validNavigation) {
endSession();
}
}
在浏览器或标签页关闭时阻止 F5、表单提交、输入点击和关闭/终止会话,在 ie8+ 和现代浏览器中测试,享受!
【讨论】:
目前不是完美但最好的解决方案:
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";
}
【讨论】:
要关闭浏览器,您可以将以下代码放入您的 web.config 中:
<system.web>
<sessionState mode="InProc"></sessionState>
</system.web>
当浏览器关闭时它会破坏你的会话,但它不适用于标签关闭。
【讨论】: