Jquery Ajax 错误处理忽略中止

Posted

技术标签:

【中文标题】Jquery Ajax 错误处理忽略中止【英文标题】:Jquery Ajax error handling to ignore aborted 【发布时间】:2011-06-16 00:10:25 【问题描述】:

我想要一个ajax调用的全局错误处理方法,这就是我现在拥有的:

$.ajaxSetup(
  error: function (XMLHttpRequest, textStatus, errorThrown) 
    displayError();
  
);

我需要忽略aborted 的错误。 errorThrown 为空,textStatuserror。如何查看aborted

【问题讨论】:

对我来说 textStatus 是“中止”。我看到这是一个老问题 - 也许它已经改变了。 对我来说,仍然是“错误”。 是的,遗憾的是它因浏览器而异。 另见:github.com/angular/angular.js/issues/15924 (2017) 如果您手动调用abort(我不确定何时会调用它),您可以传入错误消息:abort("abort") 【参考方案1】:

我今天不得不处理同样的用例。我正在开发的应用程序有这些长时间运行的 ajax 调用,这些调用可能会因 1)用户离开或 2)某种临时连接/服务器故障而中断。我希望错误处理程序仅在连接/服务器故障时运行,而不是在用户离开时运行。

我首先尝试了 Alastair Pitts 的答案,但没有成功,因为中止请求和连接失败都将状态代码和 readyState 设置为 0。接下来,我尝试了 sieppl 的答案;也没有工作,因为在这两种情况下,都没有给出响应,因此没有标题。

唯一对我有用的解决方案是为 window.onbeforeunload 设置一个侦听器,该侦听器设置一个全局变量以指示页面已被卸载。然后错误处理程序可以检查并仅在页面尚未卸载时才调用错误处理程序。

var globalVars = unloaded:false;
$(window).bind('beforeunload', function()
    globalVars.unloaded = true;
);
...
$.ajax(
    error: function(jqXHR,status,error)
        if (globalVars.unloaded)
            return;
    
);

【讨论】:

如果 ajax 请求被 javascript 中断,这将不起作用 这不是一个有效的答案。在卸载之前可以取消卸载。如果发生这种情况,所有后续的 Ajax 错误都将被忽略。 @LOST beforeunload 处理程序是用户定义的。如果要以相同的方法取消卸载,为什么要将 globalVars.unloaded 设置为 true @bluecollarcoder 我想说的是,如果你有一个大项目,遇到这个问题,你必须去修复所有 beforeunload 处理程序,仅仅添加一个新的是不够的您提供的。 beforeunload 在用户导航到另一个页面时没有被调用或调用太晚?【参考方案2】:

在现代 jQuery 中,您只需检查 request.statusText 是否等于 'abort'

error: function (request, textStatus, errorThrown) 
    if (request.statusText =='abort') 
        return;
    

【讨论】:

在 chrome 中,我可以检查“中止”。在 Firefox 中,我得到“错误”。 @bluecollarcoder 的解决方案似乎对我们来说是最好的。 是的,这取决于浏览器(常见的网络问题......)【参考方案3】:

我发现当有一个中止的请求时,status 和/或readyState 等于0

在我的全局错误处理程序中,我在方法的顶部有一个检查:

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError) 
    //If either of these are true, then it's not a true error and we don't care
    if (jqXHR.status === 0 || jqXHR.readyState === 0) 
        return;
    

    //Do Stuff Here
);

我发现这非常适合我。希望这对您或遇到此问题的其他人有所帮助:)

【讨论】:

如果 ajax 无法连接到服务器,我会得到相同的状态和 readyState。但这是我要处理的错误。只是没有中止。 是的,这将掩盖您确实希望看到的其他错误。【参考方案4】:

您需要查看传递给错误函数的 textStatus 参数。根据http://api.jquery.com/jQuery.ajax/,它可以取值“success”、“notmodified”、“error”、“timeout”、“abort”或“parsererror”。 “中止”显然是您要检查的内容。

这里有更长的注释:jquery-gotcha-error-callback-triggered-on-xhr-abort

【讨论】:

我认为我们玩弄了这个,但它并没有检测到我们拥有的那种中止错误消息。【参考方案5】:

因为 bluecollarcoders answer 不适用于 javascript 中止的 ajax 请求,所以这是我的解决方案:

var unloaded = false;
...
$(window).bind('beforeunload', function()
    unloaded = true;
);


$(document).ajaxError(function(event, request, settings) 
    if (unloaded || request.statusText == "abort") 
        return;
    
    ...

例如

handler = jQuery.get("foo")
handler.abort()

现在将被 ajaxError 处理程序忽略

【讨论】:

【参考方案6】:

在Alastair Pitts'a answer 的基础上,您还可以这样做以获得更多信息:

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError)

    
        if (jqXHR.status === 0)
        
            alert('Not connect.\n Verify Network.');
         else if (jqXHR.status == 404)
        
            alert('Requested page not found. [404]');
         else if (jqXHR.status == 500)
        
            alert('Internal Server Error [500].');
         else if (exception === 'parsererror')
        
            alert('Requested JSON parse failed.');
         else if (exception === 'timeout')
        
            alert('Time out error.');
         else if (exception === 'abort')
        
            alert('Ajax request aborted.');
         else
        
            alert('Uncaught Error.\n' + jqXHR.responseText);
        
    
);

【讨论】:

【参考方案7】:
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) 

    if (!jqXHR.getAllResponseHeaders()) 
        return;
               
); 

【讨论】:

也无济于事。对于中止的请求和与服务器的连接错误,响应标头都是空的。 @ClovisSix 是的,上面的解决方案检查响应头是否为空,并抑制恼人的错误消息。在我们运行的多个商业系统上运行良好。您能否详细说明您尝试实现的目标/您的问题是什么? 如果我们的任何请求无法连接到服务器,我们将显示消息。我们不会在手动中止时显示它们,但最大的问题是当用户导航到下一页时,这会呈现连接错误,并且无法区分中止请求和连接错误。我通过在 window.onbeforeunload 上设置一个 var 解决了这个问题。这几乎可以检测到手动中止。 这里还有更多详细信息:ilikestuffblog.com/2009/11/30/…【参考方案8】:

我在这里遇到了同样的问题,我的解决方案是在调用 abort() 之前设置一个“aborting”变量,如下所示:

aborting = true;
myAjax.abort();

并且仅在 ajax 请求的错误处理程序上显示错误,如果 abort 不是真的。

$.ajax(
    [..]
    error: function() 
        if ( !aborting ) 
            // do some stuff..
        
        aborting = false;
    
);

【讨论】:

【参考方案9】:

如果你手动中止 ajax 请求,你可以这样做:

var xhr;
function queryData () 
    if (xhr) 
      // tag it's been aborted
      xhr.hasAborted = true;

      // manually canceled request
      xhr.abort();
    

    xhr = $.ajax(
        url: '...',
        error: function () 
            if (!xhr.hasAborted) 
                console.log('Internal Server Error!');
            
        ,
        complete: function () 
           xhr = null;
        
    );

【讨论】:

以上是关于Jquery Ajax 错误处理忽略中止的主要内容,如果未能解决你的问题,请参考以下文章

错误:“CSRF 验证失败。请求中止。”在 Django 中使用 jquery ajax 时

离开页面时如何处理jQuery ajax发布错误

离开页面时如何处理jQuery ajax发布错误

jQuery 全局 ajax 错误处理程序在“本地”之前触发

包装 jQuery 的 $.ajax() 方法来定义全局错误处理

jQuery AJAX 错误处理(HTTP 状态码)