识别刷新和关闭浏览器操作
Posted
技术标签:
【中文标题】识别刷新和关闭浏览器操作【英文标题】:Identifying Between Refresh And Close Browser Actions 【发布时间】:2010-10-08 19:29:51 【问题描述】:当我们刷新页面时(F5,或者浏览器中的图标),它会首先 触发 ONUNLOAD 事件。当我们关闭浏览器(右上角的 X 图标)时,它会 触发 ONUNLOAD 事件。 现在触发 ONUNLOAD 事件时,无法区分刷新页面或关闭浏览器。 如果您有任何解决方案,请给我。
【问题讨论】:
类似问题请参见:***.com/questions/4387212/… 和 ***.com/questions/1631959/browser-window-close-event 这是如何在现代浏览器中通过 html5 api 检测页面重新加载的答案。(对我有用):***.com/questions/5004978/… 【参考方案1】:也许有人还在寻找答案……
您可以为此使用 SessionStorage!当页面重新加载但关闭时,SessionStorage 不清除。所以基本上你可以在页面加载时设置一个键/值对,但在此之前你检查键/值对是否存在。如果存在则表示页面已重新加载,如果不存在则表示用户第一次打开该页面或在新标签页中打开。
if (sessionStorage.getItem('reloaded') != null)
console.log('page was reloaded');
else
console.log('page was not reloaded');
sessionStorage.setItem('reloaded', 'yes');
这样,您可以使用onunload
事件(用户离开页面)doStuff()
,如果设置了键/值对(用户重新加载页面),则可以otherStuff()
。
【讨论】:
就刷新与关闭选项卡/浏览器而言,SessionStorage 似乎是最有希望的。如果您没有浏览器级别的设置,并且您不能要求用户更改设置,则 Cookie 会持续存在。这就是为什么在我看来,SessionStorage 要好得多。 @Mointy,感谢您的解决方案。 这是我尝试成功的方式。如果您认为这是最好的解决方案,请点赞,让更多人看到。 我尝试过这种方法用于事件 onunload,但它不起作用。 @MeiLie 这里是一个例子:codepen.io/Mointy/pen/oNGgQXx【参考方案2】:这是一个巨大的技巧,有一些限制,但它适用于大多数实际情况。
因此,如果您只需要在用户使用ctrl
+r
或cmd
+r
快捷方式时起作用的东西,您可以跟踪在您需要执行的任何操作时是否按下了r
重新加载/关闭运行。
只需创建切换rDown
变量的keydown
和keyup
事件侦听器。
let rDown = false;
window.addEventListener("keydown", event =>
if (event.key == 'r')
rDown = true;
)
window.addEventListener("keyup", event =>
if (event.key == 'r')
rDown = false;
)
然后你有你的“onunload”事件侦听器,其中侦听器函数有一个if
语句检查rDown
是否为true
。
window.addEventListener("onunload", () =>
if (!rDown)
// code that only gets run when the window is closed (or
// some psychopath reloads by actually clicking the icon)
);
【讨论】:
【参考方案3】:很遗憾,目前还没有建议或可靠的方法。
【讨论】:
【参考方案4】:归功于https://www.anandkanatt.com/how-do-i-detect-browser-window-closed-refreshed/#comment-15892。我通过使用开瓶器本身进行检查来简化它。在 Chrome 版本 78.0.3887.7 中测试。
你可以试试这个:
添加一个 refresh-close-detector.html 文件。这是示例代码:<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Processing...</title>
</head>
<body>
<script>
if (this.opener)
// the opener was refreshed, do something if you want
else
// the opener was closed, do something if you want
// you may want to close the pop up
this.close()
</script>
</body>
</html>
在要识别刷新和关闭浏览器操作的页面中,添加要卸载的事件侦听器:
window.addEventListener('unload', () =>
open('refresh-close-detector.html', '', 'width=100,height=100');
)
【讨论】:
【参考方案5】:这是一个可行的解决方案
export class BootstrapComponent implements OnInit
validNavigation = 0;
constructor(
private auth: AuthenticationService
)
ngOnInit()
const self = this;
self.registerDOMEvents();
registerDOMEvents()
const self = this;
window.addEventListener('unload', () =>
if (self.validNavigation === 0)
self.endSession();
);
document.addEventListener('keydown', (e) =>
const key = e.which || e.keyCode;
if (key === 116)
self.validNavigation = 1;
);
endSession()
const self = this;
self.auth.clearStorage();
【讨论】:
点击浏览器的刷新按钮怎么样?【参考方案6】:今天我遇到了同样的问题,并找到了一个可能的解决方案,我想与您分享。
在思考什么可以帮助区分刷新和关闭时,我想到了 cookie。我记得在没有明确过期日期的情况下设置 cookie,使其仅可用于当前会话。在浏览器关闭之前,当前会话显然是有效的。这不包括关闭选项卡,但我的问题是关于用户身份验证,我不想仅因为关闭选项卡而注销用户(我认为这与 ASP.NET 的ASPXAUTH
cookie 相同)。
所以,当用户登录并在页面加载时检查它时,我在 document.cookies
集合中放置了一个简单的 cookie:如果 cookie 仍然存在,则表示刷新或重新打开了选项卡,并且保留了用户数据,如果没有 cookie当前会话已过期,因此用户数据已被清除(与显式注销相同)。
希望这种方法对其他人有用!
【讨论】:
【参考方案7】: $(window).bind('unload', function ()
if (/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4)
console.log('firefox delete');
var data = async: false ;
endSession(data);
return null;
else
console.log('NON-firefox delete');
var data = async: true ;
endSession(data);
return null;
);
function endSession(data)
var id = 0
if (window) // closeed
id=1
$.ajax(
url: '/api/commonAPI/'+id+'?Action=ForceEndSession',
type: "get",
data: ,
async: data.async,
success: function ()
console.log('Forced End Session');
);
使用 if (window) 来确定是关闭还是重新加载。为我工作。
【讨论】:
在 Chrome 56 中,当用户关闭浏览器时,在 onunload 监听器中定义了窗口对象ForceEndSession
是什么?【参考方案8】:
我刚试过这个,它解决了这个问题: 创建一个 sessionStorage 对象,当用户关闭浏览器时该对象将被销毁。我们可以通过查看 sessionStorage 对象来判断用户是否关闭了浏览器或刷新了页面(页面刷新时 sessionStorage 对象不会被销毁)。
【讨论】:
这个答案需要代码示例。在 Chrome 56 中 sessionStorage.getItem() 在用户关闭浏览器时在 onunload 监听器中正常工作。 即使在旧版本的 IE 上设置 localStorage 对象也对我有用【参考方案9】:有办法。
我想在关闭选项卡或浏览器窗口时断开服务器上的用户,但不是在重新加载页面时(您可能希望区分重新加载/关闭事件以用于不同的目的,但您可能会从我的解决方案中受益) .基于 HTML5 的本地存储和客户端/服务器 AJAX 通信,我最终完成了以下流程:
在您的页面上,将onunload
添加到window
到以下处理程序(伪javascript):
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
在您的页面上,在body
上添加onload
到以下处理程序(伪javascript):
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 you want (I do nothing here)
在服务器上,将断开连接请求收集到一个列表中,并设置一个计时器线程,它会定期检查列表(我每 20 秒使用一次)。一旦断开连接请求超时(即 5 秒过去),断开用户与服务器的连接。如果同时接收到断线请求取消,则将对应的断线请求从列表中删除,使用户不会被断线。
如果您想区分选项卡/窗口关闭事件和跟随链接或提交的表单,此方法也适用。您只需在每个包含链接和表单的页面以及每个链接/表单登录页面上放置两个事件处理程序。
请注意,我使用unload
事件而不是beforeUnload
事件来正确管理指向附件的链接:当用户单击指向附件(例如PDF 文件)的链接时,beforeUnload
事件是分派,然后引发打开/保存弹出窗口,仅此而已(浏览器不会更改显示的页面,也不会分派unload
事件)。如果我使用beforeUnload
事件(就像我之前所做的那样),我会在没有页面更改时检测到页面更改。
这种方法仅限于支持 HTML5 本地存储的浏览器,因此您可能会为 MSIE7 等旧浏览器使用特定方法。
基于event.clientY
的其他方法不可靠,因为在单击重新加载或选项卡/窗口关闭按钮时此值为负,而在使用键盘快捷键重新加载时为正(例如 F5、Ctrl-R、.. .) 和窗口关闭(例如 Alt-F4)。依赖事件 X 的位置也不可靠,因为按钮不是在每个浏览器上都放置在相同的位置(例如左侧的关闭按钮)。
【讨论】:
我会使用sessionStorage
而不是localStorage
,因为您只是在跟踪重新加载,因此没有理由让它持续存在。
这是如何在现代浏览器中通过 HTML5 api 检测页面重新加载的答案。(对我有用):***.com/questions/5004978/…
@RajabShakirov 此答案不适用于在卸载事件期间检测刷新。
askServerToDisconnectUserInAFewSeconds
是什么?
@Kiquenet :这是对服务器的请求,要求取消在步骤 1 中发送的断开连接请求。【参考方案10】:
使用 window.onbeforeunload 事件让案例离开页面,但它会包括刷新或锚标记....使用相同的验证标志,该过程的 1 个示例是 URL 检查(初始 URL = 当前 URL)或 F5 检查使用键码进行刷新,如果是锚标记,请使用 bind()
注意* 在 Chrome 的情况下,Keycode 可能会导致问题。
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body
font-family: sans-serif;
</style>
<script src="jquery-1.9.1.js" type='text/javascript'></script>
<script type='text/javascript'>
var valid=false;
function wireUpEvents()
if(valid)
alert("Page Refreshed or Redirected");
else
window.onbeforeunload = askWhetherToClose;
function askWhetherToClose(event)
if(!valid)
var msg;
msg = "You're leaving the page, do you really want to?";
event = event || window.event;
event.returnValue = msg;
return msg;
$(document).bind('keypress', function(e)
if (e.keyCode == 116)
// or you can insert some code to check page refresh
valid = true;
//wireUpEvents();
);
$("a").bind("click", function()
//To check redirection using Anchor tags
valid = true;
//wireUpEvents();
);
$(document).ready(function()
wireUpEvents();
);
</script>
</head>
<body>
<p>Close the browser window, or navigate to <a href="http://***.com">***</a></p>
</body>
</html>
【讨论】:
当用户单击浏览器引用或返回按钮时,此代码不起作用.. 点击 X 时是否使用 FF 和 Chrome 进行测试?【参考方案11】:<html>
<body onunload="doUnload()">
<script>
function doUnload()
if (window.event.clientX < 0 && window.event.clientY < 0)
alert("Window closed");
else
alert("Window refreshed");
</script>
</body>
</html>
【讨论】:
【参考方案12】:不幸的是,正如此处的一些答案所建议的那样,检查事件的 clientY
/pageY
值并不是确定 unload
事件是否因用户而被触发的可靠方法关闭页面。
单击浏览器的关闭按钮时clientY
/pageY
是否定的原因是因为关闭按钮位于文档顶部的上方(即像素 0 上方),但重新加载按钮也是如此,这意味着单击重新加载按钮也会导致clientY
/pageY
的值为负。
沿着检查事件的 x 坐标的路径下去也是有问题的,因为浏览器关闭按钮并不总是在窗口的右侧(例如,它在 OS X 中位于左侧)并且因为一个窗口可以通过关闭其标签或通过键盘来关闭。
【讨论】:
【参考方案13】:我之前的解决方案在 IE 中对我有用。 window.event 对于 IE 以外的浏览器将未定义,因为与其他浏览器不同,“事件”在 IE 中是全局定义的。如果是其他浏览器,您需要提供事件作为参数。另外,clientX 没有为 firefox 定义,我们应该使用 pageX。
试试这样的......应该适用于IE和firefox这个......
<html>
<body>
<script type="text/javascript">
window.onunload = function(e)
// Firefox || IE
e = e || window.event;
var y = e.pageY || e.clientY;
if(y < 0) alert("Window closed");
else alert("Window refreshed");
</script>
</body>
</html>
【讨论】:
感谢 Liv 1,我尝试了此代码,但它在 Firefox 中无法正常工作,在关闭选项卡并单击刷新按钮时会出现此问题。如果您有任何其他解决方案,请给我.. 此技术不能用于可靠地确定浏览器窗口是否已关闭。以上是关于识别刷新和关闭浏览器操作的主要内容,如果未能解决你的问题,请参考以下文章