我的目标是在浏览器选项卡关闭时删除用户cookie.
可能吗?我可以处理浏览器选项卡关闭事件而无需刷新案例
如果我使用beforeunload
或unload
事件,当用户刷新页面时触发功能,我不希望这样,我想在关闭标签时运行.
我怎么能在Angular中做到这一点?
不幸的是,这不是一个简单的问题需要解决.但这是可以完成的.下面的答案是从许多不同的SO答案中合并而来的.
简单部分:
知道窗口正在被破坏.您可以使用onunload
事件句柄来检测它.
棘手的部分:
检测是否为刷新,链接跟随或所需的窗口关闭事件.删除链接并提交表单很容易:
var inFormOrLink; $('a').live('click', function() { inFormOrLink = true; }); $('form').bind('submit', function() { inFormOrLink = true; }); $(window).bind('beforeunload', function(eventObject) { var returnValue = undefined; if (! inFormOrLink) { returnValue = "Do you really want to close?"; } eventObject.returnValue = returnValue; return returnValue; });
穷人的解决方案
检查event.clientY
或event.clientX
确定点击的内容以触发事件.
function doUnload(){ if (window.event.clientX < 0 && window.event.clientY < 0){ alert("Window closed"); } else{ alert("Window refreshed"); } }
Y轴不起作用,因为它对重载或标签/窗口关闭按钮的点击是否定的,而当使用键盘快捷键重新加载(例如F5,Ctrl-R,...)和关闭窗口时(例如Alt-F4) ).由于不同的浏览器具有不同的按钮放置,因此X轴无用.但是,如果你有限,那么通过一系列if-elses运行事件坐标可能是你最好的选择.请注意,这肯定不可靠.
参与解决方案
(摘自Julien Kronegg)使用HTML5的本地存储和客户端/服务器AJAX通信.警告:这种方法仅限于支持HTML5本地存储的浏览器.
在您的页面上,将onunload
窗口添加到以下处理程序
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 } } }
在服务器上,收集列表中的断开连接请求并设置一个定时器线程,该线程定期检查列表(我每隔20秒使用一次).一旦断开请求超时(即5秒消失),断开用户与服务器的连接.如果在此期间接收到断开连接请求取消,则从列表中移除相应的断开连接请求,以便不断开用户的连接.
如果要区分选项卡/窗口关闭事件和后续链接或提交的表单,则此方法也适用.您只需将两个事件处理程序放在包含链接和表单的每个页面上以及每个链接/表单登录页面上.
结束评论(双关语):
由于您想在窗口关闭时删除cookie,我假设它是为了防止它们在将来的会话中使用.如果这是一个正确的假设,上述方法将运作良好.您将无效的cookie保留在服务器上(一旦客户端断开连接),当客户端创建新会话时,JS将默认发送cookie,此时您知道它来自较旧的会话,删除它并可选地提供在客户端设置新的.
$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 });
关于我们是否能够以万无一失的方式做到这一点,这一点备受争议.但技术上并不是很多事情可以在这里完成,因为你拥有的时间相当少,如果客户在你的行动完成之前关闭它,你就会陷入困境,而你完全怜悯客户.别忘了注入$ window.我建议不要依赖它.
javascript检测浏览器关闭选项卡/关闭浏览器
更新:
我正在研究这个问题以及一些建议.除了以上选项之外,处理此类情况的最佳方法是创建没有活动超时的会话,可能需要25-30分钟.将所有需要销毁的cookie转换为超时会话.或者,您可以设置cookie到期,但随后cookie将保留在浏览器中,直到下次登录.不到25-30分钟的会话不活动是不完全可靠的,因为如果客户端不使用浏览器10-15分钟就可以退出.我甚至尝试从链接(< a
>)或(< submit
>)或(keypress
)基于事件.问题是它能很好地处理页面刷新.但它不会消除客户端在删除cookie之前关闭浏览器或浏览器选项卡的问题.这是您在用例中必须考虑的事情,并且由于无法控制而强行权衡.最好将设计依赖于更好的架构而不是后来面对上述问题.