JavaScript、浏览器、窗口关闭-发送AJAX请求或在窗口关闭时运行脚本
我试图找出用户何时离开指定页面。找出他何时使用页面内的链接来导航是没有问题的,但我需要做一些标记,比如当他关闭窗口或键入另一个URL并按下enter键时。第二个并不重要,但第一个很重要。问题是: 当用户关闭我的页面(capture window.close事件),然后。。。这并不重要(我需要发送一个AJAX请求,但如果我能让它运行警报,我可以完成其余的工作)。使用:JavaScript、浏览器、窗口关闭-发送AJAX请求或在窗口关闭时运行脚本,javascript,browser,window,dom-events,Javascript,Browser,Window,Dom Events,我试图找出用户何时离开指定页面。找出他何时使用页面内的链接来导航是没有问题的,但我需要做一些标记,比如当他关闭窗口或键入另一个URL并按下enter键时。第二个并不重要,但第一个很重要。问题是: 当用户关闭我的页面(capture window.close事件),然后。。。这并不重要(我需要发送一个AJAX请求,但如果我能让它运行警报,我可以完成其余的工作)。使用: <body onUnload="javascript:"> 它应该捕获除关闭浏览器程序之外的所有内容。使用: &
<body onUnload="javascript:">
它应该捕获除关闭浏览器程序之外的所有内容。使用:
<body onUnload="javascript:">
它应该捕获除关闭浏览器程序之外的所有内容。有
卸载
和卸载前
javascript事件,但这些事件对于Ajax请求来说并不可靠(不能保证在其中一个事件中启动的请求会到达服务器)
因此,强烈建议不要这样做,您应该寻找替代方案
如果你确实需要这个,考虑一个“ping”样式的解决方案。每分钟发送一个请求,基本上告诉服务器“我还在这里”。然后,如果服务器不接受这样的请求超过两分钟(您必须考虑延迟等),则认为客户端离线。
另一种解决方案是使用
unload
或beforeunload
执行Sjax请求(同步JavaScript和XML),但这是完全不推荐的。这样做基本上会冻结用户的浏览器,直到请求完成,这是他们不喜欢的(即使请求只需要很少的时间)。有unload
和beforeunload
javascript事件,但这些事件对于Ajax请求来说并不可靠(不能保证在其中一个事件中启动的请求会到达服务器)
因此,强烈建议不要这样做,您应该寻找替代方案
如果你确实需要这个,考虑一个“ping”样式的解决方案。每分钟发送一个请求,基本上告诉服务器“我还在这里”。然后,如果服务器没有收到这样的请求超过两分钟(你必须考虑延迟等),你认为客户端离线。
另一种解决方案是使用
unload
或beforeunload
来执行Sjax请求(同步JavaScript和XML),但这是完全不推荐的。这样做基本上会冻结用户的浏览器,直到请求完成,这是他们不喜欢的(即使请求花费的时间很少).我同意Felix的想法,我已经用该解决方案解决了我的问题,现在我想清除服务器端解决方案:
1.从客户端向服务器发送请求
2.保存变量中接收到的最后一个请求的时间
3.检查服务器时间,并将其与上次接收的变量进行比较
请求
4.如果结果超出预期时间,则开始运行
你想在windows关闭时运行的代码…我同意Felix的想法,我已经用该解决方案解决了我的问题,现在我想清除服务器端解决方案: 1.从客户端向服务器发送请求 2.保存变量中接收到的最后一个请求的时间 3.检查服务器时间,并将其与上次接收的变量进行比较 请求 4.如果结果超出预期时间,则开始运行
您希望在windows关闭时运行的代码…我还希望实现相同的功能&这是Felix给出的答案(不保证在这些事件中启动的请求会到达服务器) 为了使请求到达服务器,我们尝试了以下代码:-
onbeforeunload = function() {
//Your code goes here.
return "";
}
我们正在使用IE浏览器&现在,当用户关闭浏览器时,他会收到确认对话框,因为
返回“;
&等待用户的确认&这段等待时间会发出到达服务器的请求。我还想实现同样的功能&从Felix那里得到了这个答案(不能保证在其中一个事件中启动的请求会到达服务器
为了使请求到达服务器,我们尝试了以下代码:-
onbeforeunload = function() {
//Your code goes here.
return "";
}
我们正在使用IE浏览器&现在,当用户关闭浏览器时,他会收到确认对话框,因为
return“”
&等待用户确认&此等待时间使请求到达服务器。所选答案正确,您不能保证浏览器发送xhr请求,但根据浏览器的不同,您可以在选项卡或窗口关闭时可靠地发送请求
通常,浏览器在xhr.send()之前关闭实际上执行。Chrome和edge看起来像是在关闭窗口之前等待javascript事件循环为空。它们也会在与javascript事件循环不同的线程中触发xhr请求。这意味着,如果可以将事件循环保持足够长的时间,xhr将成功触发。例如,我测试了发送xhrequest,然后数到100000000。对我来说,这在chrome和edge中都非常有效。如果你使用angularjs,将调用包装到$http中的$apply可以实现同样的效果
IE似乎有点不同。我认为IE不会等待事件循环变为空,甚至不会等待当前堆栈帧变为空。虽然它偶尔会正确发送请求,但发生的频率似乎要高得多(80%-90%的时间)IE将在xhr请求完全执行之前关闭窗口或选项卡,这只会导致发送部分消息。基本上,服务器接收post请求,但没有正文
为了子孙后代,这里是我使用的代码
# lifecycle.js (1K) for cross-browser compatibility
# https://github.com/GoogleChromeLabs/page-lifecycle
<script defer src="/path/to/lifecycle.js"></script>
<script defer>
lifecycle.addEventListener('statechange', function(event) {
if (event.originalEvent == 'visibilitychange' && event.newState == 'hidden') {
var URL = "https://example.com/foo";
var data = "bar";
navigator.sendBeacon(URL, data);
}
});
</script>
var URL = "https://example.com/foo";
var data = "bar";
navigator.sendBeacon(URL, data);
document.addEventListener('visibilitychange', function() {
if (document.visibilityState == 'hidden') {
// send beacon request
}
});
# lifecycle.js (1K) for cross-browser compatibility
# https://github.com/GoogleChromeLabs/page-lifecycle
<script defer src="/path/to/lifecycle.js"></script>
<script defer>
lifecycle.addEventListener('statechange', function(event) {
if (event.originalEvent == 'visibilitychange' && event.newState == 'hidden') {
var URL = "https://example.com/foo";
var data = "bar";
navigator.sendBeacon(URL, data);
}
});
</script>
$(window).bind('mouseover', (function () { // detecting DOM elements
window.onbeforeunload = null;
}));
$(window).bind('mouseout', (function () { //Detecting event out of DOM
window.onbeforeunload = ConfirmLeave;
}));
function ConfirmLeave() {
if (performance.navigation.type == 1) { //detecting refresh page(doesnt work on every browser)
}
else {
logOutUser();
}
}
$(document).bind('keydown', function (e) { //detecting alt+F4 closing
if (e.altKey && e.keyCode == 115) {
logOutUser();
}
});
function logOutUser() {
$.ajax({
type: "POST",
url: GWA("LogIn/ForcedClosing"), //example controller/method
async: false
});
}
io.on('connection', function(socket){
socket.on('disconnect', function(){
// Do stuff here
});
});