function myUnload(event) {
if (window.localStorage) {
// flag the page as being unloading
window.localStorage['myUnloadEventFlag']=new Date().getTime();
}
// notify the server that we want to disconnect the user in a few seconds (I used 5 seconds)
askServerToDisconnectUserInAFewSeconds(); // synchronous AJAX call
}
然后将onloadon主体添加到以下处理程序
function myLoad(event) {
if (window.localStorage) {
var t0 = Number(window.localStorage['myUnloadEventFlag']);
if (isNaN(t0)) t0=0;
var t1=new Date().getTime();
var duration=t1-t0;
if (duration<10*1000) {
// less than 10 seconds since the previous Unload event => it's a browser reload (so cancel the disconnection request)
askServerToCancelDisconnectionRequest(); // asynchronous AJAX call
} else {
// last unload event was for a tab/window close => do whatever
}
}
}
$window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
console.log("closing the tab so do your small interval actions here like cookie removal etc but you cannot stop customer from closing");
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Webkit, Safari, Chrome
});
**更新:**我研究了这个问题沿着给出了一些建议。除了上面的选项,处理这种情况的最好方法是创建无活动超时时间为25-30分钟的会话。将所有需要销毁的cookie转换为有超时时间的会话。或者,您可以设置cookie过期时间,但cookie会一直保留在浏览器中,直到下次登录。会话无活动时间少于25-30分钟并不完全可靠,因为如果客户端10-15分钟不使用浏览器,您可能会被注销。我甚至尝试了从链接(< a >)或(< submit >)或(keypress)的事件。问题是它很好地处理页面刷新。但它并没有消除客户端在您的cookie被删除之前关闭浏览器或浏览器选项卡的问题。这是您必须在您的用例中考虑的问题,由于无法控制它,因此必须进行权衡。最好是根据其依赖性将设计更改为更好的体系结构,而不是在以后面对所提到的问题。
yourApp.controller('exitController', ['$rootScope', '$scope', '$window', '$cookies', function($rootScope, $scope, $window, $cookies) {
//set refresh to false to start out, it will become true only when we hit the refresh page
$scope.refresh = false;
//This is where we'll actually clear our cookies in the event of a window close
$scope.clearCookies = function() {
$cookies.remove('sessionData');
$cookies.remove('ss-id');
$cookies.remove('ss-pid');
};
//When the user types any key, it will be assessed.
$scope.isRefresh = function(e) {
var keyCode = e.keyCode; //find the key that was just pressed
if(keyCode === 116) { //if the key that was pressed is F5, then we know it was a refresh
$scope.refresh = true;
}
}
//event that handles all refresh requests
window.onbeforeunload = function (e) {
if (!$scope.refresh) { //as long as the trigger for the refresh wasnt initiated by F5, we remove the cookies
$scope.clearCookies();
}
};
7条答案
按热度按时间tcbh2hod1#
不幸的是,这不是一个简单的问题,但它可以解决。下面的答案是从许多不同的SO答案中合并而来的。
**简单部分:**知道窗口正在被销毁。您可以使用
onunload
事件句柄来检测此情况。棘手的部分:
检测它是刷新、链接跟随还是所需的窗口关闭事件。删除链接跟随和表单提交非常简单:
“穷人的解决方案"
正在检查
event.clientY
或event.clientX
,以确定单击了什么触发了事件。Y轴不起作用,因为点击重新加载或选项卡/窗口关闭按钮时Y轴为负值,而使用键盘快捷键重新加载时Y轴为正值(例如,F5、Ctrl-R...)和窗口关闭(例如Alt-F4)。X轴没有用,因为不同的浏览器有不同的按钮位置。但是,如果您受到限制,那么通过一系列if-else运行事件坐标可能是最好的选择。
涉及的解决方案
(摘自Julien Kronegg)使用HTML5的本地存储和客户端/服务器 AJAX 通信。这种方法仅限于支持HTML5本地存储的浏览器。
在页面上,将
onunload
添加到窗口的以下处理程序中然后将
onloadon
主体添加到以下处理程序在服务器上,将断开连接请求收集到一个列表中,并设置一个定时器线程,该线程定期检查该列表(我每隔20秒使用一次).一旦断开连接请求超时(即5秒已过),断开用户与服务器的连接。如果在此期间接收到断开连接请求取消,则从列表中删除相应的断开连接请求,以便用户不会断开连接。
如果你想区分标签页/窗口关闭事件和跟随的链接或提交的表单,这种方法也适用。你只需要把这两个事件处理程序放在每个包含链接和表单的页面上,以及每个链接/表单登录页面上。
结束语(双关语):
由于您希望在窗口关闭时删除cookie,我假设这是为了防止它们在将来的会话中被使用。如果这是正确的假设,上面描述的方法将很好地工作。您将无效的cookie保留在服务器上(一旦客户端断开连接),当客户端创建新的会话时,JS会默认将cookie发送过来,此时您知道它来自较旧的会话,请将其删除,并选择性地提供一个要在客户端上设置的新会话。
uelo1irk2#
这是很有争议的,我们是否可以这样做或不傻瓜证明的方式。但技术上不是很多事情可以在这里做,因为你有时间是相当少,如果客户关闭它之前,你的行动完成,你有麻烦,你是在客户的怜悯完全。不要忘记注入$窗口。我建议不要依赖它。
javascript detect browser close tab/close browser
**更新:**我研究了这个问题沿着给出了一些建议。除了上面的选项,处理这种情况的最好方法是创建无活动超时时间为25-30分钟的会话。将所有需要销毁的cookie转换为有超时时间的会话。或者,您可以设置cookie过期时间,但cookie会一直保留在浏览器中,直到下次登录。会话无活动时间少于25-30分钟并不完全可靠,因为如果客户端10-15分钟不使用浏览器,您可能会被注销。我甚至尝试了从链接(<
a
>)或(<submit
>)或(keypress
)的事件。问题是它很好地处理页面刷新。但它并没有消除客户端在您的cookie被删除之前关闭浏览器或浏览器选项卡的问题。这是您必须在您的用例中考虑的问题,由于无法控制它,因此必须进行权衡。最好是根据其依赖性将设计更改为更好的体系结构,而不是在以后面对所提到的问题。aoyhnmkz3#
也许这个链接会帮助你
5us2dqdw4#
我刚刚实现了一个(相对)简单的解决方案,上面没有介绍。
于飞:
技术支持:
我发现的
beforeunload
和unload
事件的逻辑是:document.visibilityState
的值:| | 卸载前|卸载|
| - -|- -|- -|
| 选项卡已关闭|'隐藏'|'隐藏'|
| 选项卡已刷新|'可见'|'隐藏'|
因此,您可以使用visibilityState和beforeunload事件来区分用户是刷新了还是关闭了选项卡。我使用了一些额外的
localStorage
元素来检查注销状态,但对于5年后遇到此问题的任何人来说,可能都不需要这样做。有关MDN上
document.visibilityState
的更多信息:https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilityStatecwtwac6a5#
如果您的目标是在浏览器关闭时删除Cookie,请不要设置过期。没有过期的Cookie将在浏览器关闭时删除。
你真的不需要知道用户是否关闭了他们的浏览器。我相信有其他的方法来完成你想做的事情。
c0vxltue6#
我知道这个问题已经有一段时间没有被问到了,但是我想我也应该给出我的答案。我发现的在不丢失cookie的情况下重新加载页面,以及在窗口或标签页关闭时删除cookie的最好方法是使用ng-keydown来监视F5按键(键码116)。
HTML格式
控制器
}]);
yrdbyhpb7#
参考编号:https://www.techiediaries.com/angular-leave-browser-beforeunload-event/
使用窗口的HostListener的最佳方法是:在应用程序组件或Tab键关闭事件的目标组件中执行beforeunload