如何检测因网络断开而导致的Ajax调用失败

20

我正在使用 jQuery 的 ajax 方法向 Web 服务器发送大量数据,客户端只有在收到来自服务器的确认后才会响应。现在假设在 ajax 调用的中途网络连接断开了,那么如何检测这种情况。

$.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不等,并且计算服务器响应时间是不可行的。


1
使用 alert() 函数并观察 textStatuserrorThrown 的变化,以了解不同故障类型的适当代码。您应该能够找到相应的代码。 - Blender
请查看以下链接:https://dev59.com/vHVC5IYBdhLWcg3wxEJ1 和 https://dev59.com/9HI-5IYBdhLWcg3wq6do。 - gopi1410
@Blender 当网络断开时,任何参数都不会发生变化,并且不会进入错误函数。 - Ritesh Chandora
@gopi1410 每当 Ajax 请求完成时出现错误,jQuery 就会触发 ajaxError 事件。而在我的情况下,Ajax 请求并没有完成。 - Ritesh Chandora
我还没有深入研究Offline.js,但它可能有一些有用的相关代码。 - But I'm Not A Wrapper Class
显示剩余2条评论
6个回答

6

请尝试以下步骤:

首先,每5秒钟使用setInterval创建一个“ping” ajax调用。

function server_ping()
    {
        $.ajax({
            url:"url to ping",
            type: "POST"
        });
    }
    var validateSession = setInterval(server_ping, 5000);

然后配置您的.ajaxError陷阱:
$(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的错误。


3
如果您的服务器没有太多负载,那么您可以使用计时器在传输数据时定期开始检测连接(例如每5秒钟进行另一个ajax调用)。现在您可以使用超时。
顺便说一下, 1)超时并不总是意味着网络错误。有时候服务器宕机也会导致“超时”。 2)如果客户端设备上的驱动程序已关闭,则xhr.status = 0,并且没有超时。

2

我遇到了类似的问题,并通过简单的try/catch和重新尝试延迟(例如2秒)来解决它:

function myAjaxMethod()
{
  try 
  {
    $.ajax({ ... });
  } catch (err) 
  { 
    console.log(err.message); 
    setTimeout(function(){myAjaxMethod(),2000});
  }
}

1
我曾经遇到过和你类似的情况,通过每5秒进行一次网络检查并在网络断开时手动中止ajax请求来解决问题。
在Jquery ajax调用的beforeSend事件中获取ajax XmlHttpRequest对象,并在网络故障的情况下使用该对象中止ajax请求。
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);

0

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

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

请参考 Jquery 的 ajax():http://api.jquery.com/jQuery.ajax/#toptions,您将在那里获得更多信息!

我对您的问题的想法[更新]

@RiteshChandora,我理解您在这里的担忧。但是我可以建议您做两件事情。

  1. 由于您的帖子数据范围从200kb到5mb不等,您可能需要选择最大超时时间并触发相应操作。是的,这可能会有问题,但是根据您选择的设计,监视POST进度的唯一方法就是这样做。如果不这样做,请参见第2点。

  2. 我已经了解了流程,您要求用户将响应Json从FB复制到您的URL。这里存在一些问题,

  3. JSON数据包含用户的敏感信息,并且他在没有SSL加密的情况下将其发布在URL上。

  4. 为什么要提示用户将获取的数据发布到您的服务器上?如果您使用服务器端脚本,那么这将更容易。此外,在这种情况下,您永远不应该从客户端向服务器发送大量数据,因为您可以从FB服务器->您的服务器检索相同的数据。

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

这样,所有负担都将由您的服务器承担,而且用户无需在您的URL上进行任何糟糕的JSON发布。

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

抱歉,我错过了你关于超时的注释。 你能否尝试捕获errorThrown?当服务器未找到时,它是“NOT FOUND”。你不能触发“NOT FOUND”的errorThrown吗? 这里:http://jsfiddle.net/epinapala/y4cva/ - Eswar Rajesh Pinapala
@Rajesh 你提出的答案仅在服务器响应时有效。但是我的问题是,如果Ajax调用在完成过程中被取消,那么如何检测这种情况。我想向用户发送一条消息并回滚到先前的状态。 - Ritesh Chandora
你是在说,当调用甚至未到达服务器时如何处理情况?在数据发布到服务器之前就被取消了? 如果是这种情况,是什么导致了ajax调用在中途被取消?甚至在它到达服务器之前? 如果你说是网络问题,那么你仍然应该尝试捕获在这种情况下返回的错误信息,你试过了吗? - Eswar Rajesh Pinapala
@Rajesh,是的,我测试了错误抛出,它没有起作用。我的意思是,当您使用ajax调用发送1MB数据并且假设只有50%的数据被提交,然后ajax调用失败时,该如何处理这种情况。我检查了您建议的链接,它说要使用TIME OUT选项,但我无法使用。 - Ritesh Chandora
@Ritesh .. 你能在jsfiddle.net上发布示例代码吗?除了服务器不可用之外,我真的想知道是什么导致Ajax请求在完成之前停止?帮助我们快速解决这个问题的是1- Ajax请求在上传50%数据后停止的原因是什么? - Eswar Rajesh Pinapala
显示剩余11条评论

-5
   error: function(xhr, textStatus, thrownError)
                    {
                       alert(xhr.status);
                       alert(thrownError);
                       alert(textStatus);

                    }

试试它们... TextStatus(除了null之外)还有“timeout”、“error”、“abort”和“parsererror”。 当发生HTTP错误时,thrownError会接收HTTP状态的文本部分,如“未找到”或“内部服务器错误”。

如果断开互联网连接,则不会收到响应,并且最多只会收到超时消息。


一些参考链接...http://api.jquery.com/jQuery.ajax/ 和 http://api.jquery.com/ajaxError/ - Kabilan S
2
你提供的答案仅在服务器响应时有效。但我想问的是,如果 Ajax 调用在完成中间被取消,如何检测到这种情况?我想向用户显示一条消息并回滚到先前的情况。 - Ritesh Chandora

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接