Javascript 卸载时向服务器发送ajax数据,超时

Javascript 卸载时向服务器发送ajax数据,超时,javascript,ajax,html,xmlhttprequest,Javascript,Ajax,Html,Xmlhttprequest,当用户离开我的web应用程序时,我需要向服务器发送一些数据。最好的方法是使用,但浏览器支持较差。我尝试了同步ajax请求,但我了解到这是一种糟糕的做法——如果服务器不返回响应,并且无法设置超时,则选项卡将被冻结。所以我需要在所有浏览器上可靠地发送数据,而不需要超时,以防服务器响应不够快 我已经实现了它,我将回答这个问题,但是任何建议或其他解决方案都是非常受欢迎的。好的,因此可以使用异步XHR和2个事件完成:beforeunload和unload 我曾尝试在一个事件中执行此操作,但在循环完成之前不

当用户离开我的web应用程序时,我需要向服务器发送一些数据。最好的方法是使用,但浏览器支持较差。我尝试了同步ajax请求,但我了解到这是一种糟糕的做法——如果服务器不返回响应,并且无法设置超时,则选项卡将被冻结。所以我需要在所有浏览器上可靠地发送数据,而不需要超时,以防服务器响应不够快


我已经实现了它,我将回答这个问题,但是任何建议或其他解决方案都是非常受欢迎的。

好的,因此可以使用异步XHR和2个事件完成:beforeunload和unload

我曾尝试在一个事件中执行此操作,但在循环完成之前不会发送请求,即使请求是在循环之前发送的

在beforeunload处理程序中,发送异步请求并保存当前时间。然后在卸载处理程序中,放置一个while循环,如果没有足够的时间或服务器响应(检查readyState),该循环将继续。 循环结束时,浏览器可以自由卸载窗口

这是密码。如果浏览器支持,我还启用了发送信标

var unloadRequest = null, 
       requestStartTime = null,
       isBeaconSupported = (navigator && typeof navigator.sendBeacon === 'function');

  window.onbeforeunload = function() {

     if (isBeaconSupported) {

            unloadRequest = new XMLHttpRequest();
            unloadRequest.withCredentials = true;
            unloadRequest.open('POST', '/beacon', true);
            unloadRequest.setRequestHeader("Content-Type", "text/plain");

            requestStartTime = performance.now();
            unloadRequest.send(JSON.stringify({ test: true, _sentBy: 'XMLHttpRequest' }));

  }

  //return true;

};

window.onunload = function() {

  if (isBeaconSupported) {

    navigator.sendBeacon('/beacon', JSON.stringify({ test: true, _sentBy: 'beacon' }))

  } else if (unloadRequest) {

    //continue the loop if time is left and the request havent finished
    while (requestStartTime + 3000 > performance.now() && unloadRequest.readyState !== XMLHttpRequest.DONE) {

      //console.log(unloadRequest.readyState);

      }

      console.log('request finished or timed out')
      console.log('it took: ' + (performance.now() - requestStartTime) + 'ms');

  }         

};