我正在开发一个聊天应用程序。如果用户在没有注销的情况下关闭浏览器窗口,我想要终止会话。我使用'beforeunload'函数,但是当一个回发事件被触发时它也会触发,因此对我来说不好。
如果有人对此有所了解,请提供帮助。
答案 0 :(得分:7)
如果使用轮询来获取聊天数据,如果在给定时间内没有收到来自客户端的轮询请求,则应该终止会话。
客户端:
setInterval (pollData, 10000); /* poll for new data each 10 seconds */
服务器:
if (clientX.LastPollTime is over 30 seconds ago) {
clientX.killSession();
}
答案 1 :(得分:1)
我建议你使用Alexanders方法,但在大多数情况下,设置间隔时间不会单独解决这个问题。因为用户可能闲置一段时间并且可能超过超时时间。
为了避免这种情况,你需要再添加一个条件。
如果用户在超时期间闲置,则只需向服务器发出AJAX请求,并将客户端状态更新为空闲。
如果用户在某段时间内服用,这将避免注销会话。
如果服务器未在指定时间内收到客户端的任何响应并且状态未更新为空闲(在浏览器关闭或任何应用程序挂起期间),则可以终止会话。
答案 2 :(得分:1)
是的,亲爱的,它是好的,但是第二件事,因为你指定该服务器没有收到任何响应,在我的代码服务器中只检查应用程序会话,它会找到它以便它可以工作。我希望如果用户没有注销然后页面被杀死,那么我们如何调用客户端的任何ajax或xmlhttp请求将应用程序会话设置为离线。
所以请大家告诉我这是唯一不顺利的事情。和thanx的回应。
答案 3 :(得分:1)
正如您所说,当用户点击链接或刷新页面时,事件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中发布了这个答案。我不确定我应该回答多个类似的问题或发表参考文献吗?
答案 4 :(得分:1)
如果你控制了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();
在客户端,您可以使用Daniel Melo的答案。我正在使用它进行一个小改动:
function endSession() {
// $.get("<whatever url will end your session>");
// kill the session id
document.cookie = 'MYOWNSESSID=; path=/';
}
唯一悬而未决的问题是,我无法将事件连接到输入类型[按钮],我已经用原始代码进行了连接,但一切正常。