jQuery Ajax错误处理可忽略中止


80

我想为ajax调用提供一种全局错误处理方法,这就是我现在所拥有的:

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

我需要忽略的错误abortederrorThrown为null,textStatuserror。我该如何检查aborted


4
对我来说,textStatus是“中止”。我看到这是一个老问题-也许它已经改变了。
jackocnr

对我来说,这仍然是“错误”。
贾尼斯·埃默里斯(JānisElmeris)

是的,遗憾的是,它取决于浏览器。
Christophe Roussy


1
如果您是abort手动致电(而且我不确定何时会调用),您可以传递错误消息:abort("abort")
MyiEye

Answers:


52

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

我首先尝试了Alastair Pitts的答案,但是由于中止的请求和连接失败都将状态代码和readyState设置为0,所以它不起作用。也没有用,因为在两种情况下都没有给出响应,因此没有报头。

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

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

4
如果ajax请求被JavaScript中断,则无法使用
Sano J

1
这不是有效答案。在beforeunload中可以取消卸载。如果发生这种情况,所有后续的Ajax错误都将被忽略。
LOST 2015年

@LOSTbeforeunload处理程序是用户定义的。true如果要以相同的方法取消卸载,为什么还要将globalVars.unloaded设置为?
bluecollarcoder 2015年

@bluecollarcoder我要说的是,如果您有一个大项目,遇到此问题,则必须去解决所有的beforeunload hanlders,仅添加您提供的新项目是不够的。
LOST

beforeunload当用户导航到另一个页面或被调用为时已晚时不会调用?
Christophe Roussy '18

41

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

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

4
在Chrome中,我可以检查“中止”。在Firefox中,我得到“错误”。@bluecollarcoder的解决方案对我们来说似乎是最好的。
foxont​​herock

是的,这取决于浏览器(通常的网络问题...)
Christophe Roussy

21

我发现的是,当请求中止时,thestatus和/或readyStateequal 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
});

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


3
如果ajax无法连接到服务器,我将获得相同的状态和readyState。但这是我要处理的错误。只有中止没有。
米塔尔(Mitar)

是的,这将掩盖您确实希望看到的其他错误。
Christophe Roussy '18


4

由于bluecollarcoders答案不适用于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处理程序忽略


3

Alastair Pitts'a答案的基础上,您也可以这样做以获得更多信息:

$(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);
        }
    }
});

2
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {

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

1
也没有帮助。对于中止的请求和与服务器的连接错误,响应标头为空。
克洛维斯2013年

@ClovisSix是的,以上解决方案检查响应标头是否为空,并消除令人讨厌的错误消息。在我们运行的多个商业系统上运行良好。您能否提供更多详细信息,以尝试解决/您的问题是什么?
sieppl

如果我们有任何请求无法连接到服务器,我们将显示消息。我们没有显示手动中止它们,但是最大的问题是当用户导航到下一页时,这会导致连接错误,并且无法区分中止的请求和连接错误。我通过在window.onbeforeunload上设置var解决了该问题。几乎可以检测到手动中止。
克洛维斯2013年

而且,这里更多的细节:ilikestuffblog.com/2009/11/30/...
克里斯托夫•鲁西

0

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

aborting = true;
myAjax.abort();

如果abort不正确,则仅在ajax请求的错误处理程序上显示错误。

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

0

如果您手动中止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;
        }
    });
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.