关于javascript:如何检测网络断开导致的Ajax呼叫失败

How to detect Ajax call failure due to network disconnected

我使用jquery ajax方法向web服务器发送大量数据,客户端只在收到服务器的确认后才响应,现在假设网络连接在ajax调用的MIDDLE中丢失,那么如何检测这种情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$.ajax({
         url:'server.php',
         data:'lots of data from 200KB to 5MB',
         type:'post',
         success: function(data)
                    {
                        alert('Success');
                      //some stuff on success

                    },
          error: function(XMLHttpRequest, textStatus, errorThrown)
                    {
                        alert('Failure');
                      //some stuff on failure
                    }
        });

这是我的代码,如果让互联网断开连接,它在ajax调用中间不会出错。

注意:我无法使用超时,因为数据大小从200kb到5MB不等,服务器响应时间计算不可行。


试试这个:

首先每隔5秒用setInterval创建一个"ping"ajax调用

1
2
3
4
5
6
7
8
function server_ping()
    {
        $.ajax({
            url:"url to ping",
            type:"POST"
        });
    }
    var validateSession = setInterval(server_ping, 5000);

然后武装你的.ajaxError陷阱:

1
2
3
4
5
6
7
$(document).ajaxError(function( event, request, settings ) {
        //When XHR Status code is 0 there is no connection with the server
        if (request.status == 0){
            alert("Communication with the server is lost!");
        }

    });

记住Ajax调用默认是异步的,所以当ping进入服务器并且请求无法到达服务器时,XHR状态的值为0,并且.ajaxError将触发,你必须捕获错误并处理你的方式想要它。

然后,您可以将数据发送到服务器,如果在发送数据时连接丢失,则会收到ping报告的错误。


如果您的服务器不是很拥挤,可能您可以使用计时器在开始传输数据时定期开始检测连接(通过使用另一个ajax调用,例如每5秒)。现在你可以使用超时。

顺便说一句,
1)超时并不总是意味着网络错误。有时服务器的关闭也导致"超时"

2)如果驱动程序在客户端设备上关闭,则xhr.status = 0,并且没有超时


我有一个类似的问题,并通过simpel try / catch和(比方说)2秒的重试延迟来解决它:

1
2
3
4
5
6
7
8
9
10
11
function myAjaxMethod()
{
  try
  {
    $.ajax({ ... });
  } catch (err)
  {
    console.log(err.message);
    setTimeout(function(){myAjaxMethod(),2000});
  }
}

我遇到了类似你的情况并通过每5秒进行一次网络检查来修复它,如果网络断开,我会手动中止ajax请求,这将结束ajax请求。

这里我在Jquery ajax调用的beforeSend事件中获取ajax XmlHttpRequest,并在网络出现故障时使用该对象中止ajax请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var interval = null;
var xhr = null;

$.ajax({
     beforeSend: function(jqXHR, settings) {  
          xhr = jqXHR;  // To get the ajax XmlHttpRequest
     },
     url:'server.php',
     data:'lots of data from 200KB to 5MB',
     type:'post',
     success: function(data)
                {
                    alert('Success');
                  //some stuff on success

                },
      error: function(XMLHttpRequest, textStatus, errorThrown)
                {
                    alert('Failure');
                  //some stuff on failure
                },
      complete: function(data)
                {
                    alert('Complete');
                    //To clear the interval on Complete
                    clearInterval(interval);
                },
    });

interval = setInterval(function() {
    var isOnLine = navigator.onLine;
        if (isOnLine) {
            // online
        } else {
             xhr.abort();
        }
     }, 5000);

尝试添加超时:构建$ .ajax({})。

还要确保设置cache:false,有时候很有帮助。

请参阅Jquery的ajax():http://api.jquery.com/jQuery.ajax/#toptions

您将获得更多信息!

我的想法是你的问题[更新]

@RiteshChandora,我理解你的关注点。我怎么能建议你做两件事。

  • 由于您的发布数据范围从200kb到5mb,您可能希望选择最大超时。并触发相同的。是的,这可能会有问题,但是根据您选择的设计,监控POST进度的唯一方法就是这样做。如果没有,请参见第2点。

  • 我完成了流程,您要求用户将响应Json从FB复制到您的URL。这里有一些问题,

  • json数据具有关于用户的敏感信息,并且他将其发布在没有SSL加密的URL上。

  • 为什么要提示用户将获取的数据发布到您的服务器上?如果您使用服务器端脚本应该会更容易。此外,您不应该在这样的情况下将大量数据从客户端发布到服务器,在这些情况下,您可以在服务器端检索相同的FBserver->您的服务器。

  • 我建议的解决方案:在用户通过身份验证后,在服务器端检索他的好友列表。在服务器端执行任何操作,并在用户屏幕上显示结果。

    这样,您的服务器将承担所有负担,也不需要用户在您的网址上进行任何令人讨厌的json发布。

    顺便说一下,你的app想法很酷。


    1
    2
    3
    4
    5
    6
    7
       error: function(xhr, textStatus, thrownError)
                        {
                           alert(xhr.status);
                           alert(thrownError);
                           alert(textStatus);

                        }

    试试吧..
    TextStatus(除了null)是"超时","错误","中止"和"parsererror"。
    发生HTTP错误时,thrownError会收到HTTP状态的文本部分,例如"Not Found"或"Internal Server Error"。

    如果Internet断开连接,则不会收到响应,并且最大值将是超时消息。