浏览器或选项卡closures时closures/closures会话
有人可以告诉我,当用户closures浏览器时,如何closures/终止会话? 我正在使用状态服务器模式为我的asp.net Web应用程序。 onbeforeunload
方法不正确,因为它在用户刷新页面时触发。
你不能。 HTTP是一种无状态的协议,所以你不能告诉用户何时closures浏览器,或者他们只是坐在那里用一个开放的浏览器窗口什么也不做。
这就是会话超时的原因 – 您可以尝试减less超时,以便更快地closures不活动的会话,但这可能会导致合法用户提早超时。
如上所述,浏览器在closures时不会让服务器知道。
不过,还有一些方法可以实现接近这种行为。 您可以放置一个小的AJAX脚本,定期更新服务器的浏览器是否打开。 你应该把这个和用户所做的动作联系起来,这样你就可以把一个空闲的会话和一个已经closures的会话超时。
正如你所说的事件window.onbeforeunload当用户点击链接或刷新页面触发,所以它甚至不会结束会话。
http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx描述了window.onbeforeonload被触发的所有情况。 (IE)
但是,您可以在页面上放置一个JavaScript全局variables,以标识不应触发注销的操作(例如,通过使用来自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; });
全局variables是在页面级定义的。 如果此variables未设置为true,则事件windows.onbeforeonload将终止会话。
一个事件处理程序被附加到页面中的每个链接和表单,以将该variables设置为true,从而防止会话被终止,如果用户只是提交表单或单击链接。
function endSession() { $.get("<whatever url will end your session>"); }
如果用户closures浏览器/选项卡或导航,会话将被终止。 在这种情况下,全局variables没有设置为true,脚本将对您想要结束会话的任何URL执行AJAX调用
这个解决scheme是服务器端技术不可知的。 这并没有经过充分的testing,但在我的testing中似乎工作得很好
我这样做:
$(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(); } }
对于浏览器closures,你可以把下面的代码放到你的web.config中:
<system.web> <sessionState mode="InProc"></sessionState> </system.web>
当浏览器closures时,它会破坏你的会话,但是它不能用于制表符closures。
当机器由于停电而意外关机时,不能杀死会话variables。 只有当用户闲置很长时间或正确注销时才有可能。
请参考以下步骤:
- 首先创build一个SessionClear.aspx页面,并编写清除会话的代码
-
然后在您的页面或母版页中添加以下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 onbeforeunload="bodyUnload();" onmousedown="somefunction()">
不完美,但现在最好的解决scheme:
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.onbeforeunload = function () { if (!validNavigation) { endSession(); } }
的jsfiddle
防止F5,当浏览器或标签closures时,提交,input点击和closures/closures会话,在ie8 +和现代浏览器中testing,享受!