Javascript 如何检测由于网络断开导致的 Ajax 调用失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11044694/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 04:12:56  来源:igfitidea点击:

How to detect Ajax call failure due to network disconnected

javascriptajaxjquery

提问by Ritesh Chandora

I am sending lots of data using jquery ajax method to web sever and client side respond only after receiving acknowledgment from server, now suppose network connection lost in MIDDLE of ajax call then how to detect this situation.

我正在使用 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
                    }
        });

This is my code and and it does not give error in middle of ajax call if get internet is disconnected.

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

NOTE : I cant use time out because data size is vary from 200kb to 5MB and server response time calculation is not feasible.

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

回答by DariusVE

Try this:

尝试这个:

First create a "ping" ajax call with setInterval every 5 seconds

首先每 5 秒创建一个带有 setInterval 的“ping”ajax 调用

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

then arm your .ajaxError trap:

然后武装你的 .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!");
        } 

    });

Remember Ajax calls are Asynchronous by default, so when the pings are going to the server and the request cannot reach the server the value on the XHR status is 0, and the .ajaxError will fire and you must catch the error and handle the way you want it.

请记住,默认情况下 Ajax 调用是异步的,因此当 ping 发送到服务器并且请求无法到达服务器时,XHR 状态上的值为 0,并且 .ajaxError 将触发,您必须捕获错误并按照您的方式处理想要它。

Then you can send your data to the server, if the connection is lost when sending the data you get the error reported by the ping.

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

回答by lucian

If your server was not very crowded, probably you could use a timer to start detecting the connection regularly when you start transferring the data (by using another ajax calling, for instance each 5 seconds). now you can use timeout.

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

Btw, 1)timeout doesn't always means network error. sometimes server's down also causes "timeout"

顺便说一句,1)超时并不总是意味着网络错误。有时服务器停机也会导致“超时”

2)if the driver is down on client device, xhr.status = 0, and no timeout

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

回答by Uvaise

I faced a similar situation like yours and fixed it by having a network check for every 5 seconds and if network is disconnected i would abort the ajax request manually which will end the ajax request.

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

Here i get the ajax XmlHttpRequest in the beforeSend event of the Jquery ajax call and use that object to abort the ajax request in case of network failure.

在这里,我在 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);

回答by Morten Madsen

I had a similar problem and solved it with a simpel try/catch and a re-try delay of (say) 2 seconds:

我有一个类似的问题,并通过一个简单的尝试/捕获和(比如)2 秒的重试延迟解决了它:

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

回答by Eswar Rajesh Pinapala

Try adding timeout: while constructing your $.ajax({}).

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

Also make sure to set cache: false, helpful sometimes.

还要确保设置缓存:false,有时会有所帮助。

Refer to Jquery's ajax() : http://api.jquery.com/jQuery.ajax/#toptions

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

You will get much more information there!

您将在那里获得更多信息!

My thought s on your problem[updated]

我对你的问题的看法[更新]

@RiteshChandora , I understand your concern here. How ever I can suggest you to do 2 things.

@RiteshChandora ,我理解您的担忧。我怎么能建议你做两件事。

  1. As you have post data ranging from 200kb to 5mb, you might want to choose a maximum timeout. and trigger for the same. Yes, this might be problematic, but with the design you chosen, the only way to monitor the POST progress is to do this way. if not, see point 2.

  2. I went through the flow, you are asking the user to copy the response Json from FB to your url. there are some problems here,

  3. The json data has sensitive information about the user, and he is posting it on a url without SSL encryption.

  4. Why should you prompt the user to post the acquired data on to your server? it should be easier if you user sever side scripts. Also you should never post huge data from the client to the server in occasions like these, where you could retrieve the same form the FBserver->your sevrer on the server side.

  1. 由于您有 200kb 到 5mb 的发布数据,您可能需要选择最大超时。并触发相同。是的,这可能有问题,但是对于您选择的设计,监控 POST 进度的唯一方法就是这样做。如果不是,请参阅第 2 点。

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

  3. json 数据包含有关用户的敏感信息,他将其发布在没有 SSL 加密的 url 上。

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

My suggested solution : after the user is authenticated , retrieve his friends list on the server side. do whatever you want on the server side, and display the result on the users screen.

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

This way all the burden will be taken by your server, also there is no need for the user to do any nasty json posting on your url.

这样所有的负担都将由您的服务器承担,用户也无需在您的 url 上发布任何令人讨厌的 json 文件。

Btw, your app idea is cool.

顺便说一句,你的应用创意很酷。

回答by Kabilan S

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

                    }

Try them..TextStatus (besides null) are "timeout", "error", "abort", and "parsererror". When an HTTP error occurs, thrownError receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error."

试试看..TextStatus(除了空值)是“超时”、“错误”、“中止”和“解析器错误”。当发生 HTTP 错误时,throwedError 接收 HTTP 状态的文本部分,例如“未找到”或“内部服务器错误”。

If Internet disconnects,the response wont be received and maximum it would be a timeout message..

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