正如你所说,当用户单击链接或刷新页面时会触发事件 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 发布了这个答案。我不确定是否应该回答多个相似的问题或发布参考?