在“离线”事件中中止Ajax调用

时间:2018-11-05 03:37:18

标签: javascript ajax internet-explorer

我想让我的网站检测用户何时脱机以及何时脱机-中止所有正在进行的Ajax POST呼叫。目前,我有以下代码:

$('#form').on('submit', function(event) {
    event.preventDefault();

    var post_data = new FormData($("#form")[0]);

    $.ajax({
      xhr: function() {
        var xhr = new window.XMLHttpRequest();
        var started_at = new Date();

        xhr.upload.addEventListener("progress", function(evt) {

          if (!navigator.onLine && xhr.readyState < 4) {

            alert("Internet connection was lost. Data transfer has been     aborted.")
            xhr.abort()

          } else {
            // some logic
          }
        }

        return xhr;
    },
    url: '#',
    type: "POST",
    data: post_data,
    processData: false,
    contentType: false,
    dataType: "json",
    timeout: 360000,
    success: function(response) {
        // some logic
    }
  });
})

只要在“加载”事件发生之前,只要“进度”事件处于打开状态,上面的代码就可以很好地使用脱机事件检测。但是,在“加载”事件和服务器响应之间(大约需要1-20秒(由于某些服务器端数据操作)),我留给用户等待一些网站响应,如果连接断开,该响应可能永远不会出现。 / p>

我尝试添加以下内容:

$(document).ready(function() {
...
  window.addEventListener('offline', function(e) { 
    console.log('Event checker: offline');
    $.ajax().xhr.abort()
  });
...
})

但是,这一点对我都不起作用-我很确定'$ .ajax()。xhr.abort()'行不是试图从外部终止Ajax调用的正确方法。 Ajax功能。

我也曾尝试为'readyStateChange'事件使用事件监听器,但是状态3和4仅在服务器回复时才出现,这又使我陷入了“进度”事件发生后连接丢失的情况允许感知状态更改3和4。

我还考虑过将超时属性添加到Ajax定义中,但这是指定为readyStates 1-4完成的时间,因此如果我让用户等待几分钟再让他等待,那将有些笨拙知道他的连接超时了,应该再次尝试...

更新

因此,我找到了一种实现上述方法的方法,并评估了它在Chrome中的运行效果。拍拍我的背。但是,Internet Explorer决定以一种惊人的方式不同意。

首先,代码-将Ajax定义分配给全局变量使我可以通过全局事件侦听器访问它:

$('#form').on('submit', function(event) {
    event.preventDefault();

    var post_data = new FormData($("#form")[0]);

    xhr = $.ajax({
      xhr: function() {
        var xhr = new window.XMLHttpRequest();
        var started_at = new Date();

        xhr.upload.addEventListener("progress", function(evt) {

          if (!navigator.onLine && xhr.readyState < 4) {

            alert("Internet connection was lost. Data transfer has been     aborted.")
            xhr.abort()

          } else {
            // some logic
          }
        }

        return xhr;
    },
    url: '#',
    type: "POST",
    data: post_data,
    processData: false,
    contentType: false,
    dataType: "json",
    timeout: 360000,
    success: function(response) {
        // some logic
    }
  });
})


$(document).ready(function() {
...
  window.addEventListener('offline', function(e) { 
    console.log('Event checker: offline');
    xhr.abort()
  });
...
})

Chrome可以按照我的理解理解字母的代码,但是Internet Explorer通过以下几位使事情变得有趣/烦人:

        xhr.upload.addEventListener("progress", function(evt) {

          if (!navigator.onLine && xhr.readyState < 4) {

            alert("Internet connection was lost. Data transfer has been     aborted.")
            xhr.abort()

          } else {
            // some logic
          }
        }

实际上,IE一直一直在调用该代码,如果不幸的用户处于脱机状态,它将用无穷无尽的警报窗口来对屏幕进行垃圾处理。我猜想这是IE对Ajax事件监听器的古怪实现...

反正有人对如何解决这个问题有任何想法吗?

1 个答案:

答案 0 :(得分:0)

所以,两天后,我终于找到了解决问题的方法-这是竞赛情况,由以下行触发:

alert("Internet connection was lost. Data transfer has been aborted.")
xhr.abort()

将其重写为以下内容可解决此问题:

xhr.abort()
alert("Internet connection was lost. Data transfer has been aborted.")

我必须这样说:第一次IE在某些方面太快了。永远。