JavaScript、浏览器、窗口关闭-发送AJAX请求或在窗口关闭时运行脚本

JavaScript、浏览器、窗口关闭-发送AJAX请求或在窗口关闭时运行脚本,javascript,browser,window,dom-events,Javascript,Browser,Window,Dom Events,我试图找出用户何时离开指定页面。找出他何时使用页面内的链接来导航是没有问题的,但我需要做一些标记,比如当他关闭窗口或键入另一个URL并按下enter键时。第二个并不重要,但第一个很重要。问题是: 当用户关闭我的页面(capture window.close事件),然后。。。这并不重要(我需要发送一个AJAX请求,但如果我能让它运行警报,我可以完成其余的工作)。使用: <body onUnload="javascript:"> 它应该捕获除关闭浏览器程序之外的所有内容。使用: &

我试图找出用户何时离开指定页面。找出他何时使用页面内的链接来导航是没有问题的,但我需要做一些标记,比如当他关闭窗口或键入另一个URL并按下enter键时。第二个并不重要,但第一个很重要。问题是:

当用户关闭我的页面(capture window.close事件),然后。。。这并不重要(我需要发送一个AJAX请求,但如果我能让它运行警报,我可以完成其余的工作)。

使用:

<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
      });
 });