【问题标题】:Ajax - Handle 404 error in jquery $.whenAjax - 处理 jquery $.when 中的 404 错误
【发布时间】:2018-01-10 23:10:42
【问题描述】:

所以我有以下代码:

function ajax1(url) {
    return $.ajax({
        url: url
    });
}

function ajax2(url) {
    return $.ajax({
        url: url
    });
}

function ajax3(url) {
    return $.ajax({
        url: url
    });
}

function ajax4(url) {
    return $.ajax({
        url: url
    });
}

然后我运行 Ajax 调用并使用 $.when 访问每个调用返回的数据:

$.when(ajax1(url), ajax2(url), ajax3(url), ajax4(url)).done(function(a1, a2, a3, a4){

});

现在,假设其中一个 Ajax 调用 ajax2 将返回 404 错误。

即使返回 404 错误,如何才能阻止脚本执行并仍然返回某些内容(例如 false,要使用 a2 变量访问)?

非常感谢您。

【问题讨论】:

标签: jquery ajax


【解决方案1】:

jQuery 3 Deferred 符合Promises A+。这意味着您可以在请求承诺中添加catch()

每当您从catch()返回时,它都会解析承诺,并且返回的任何内容都将传递给链中的下一个then()

function ajax1(url) {
  return $.ajax({
      url: url
    })
    .then(data => data)
    .catch(resolveFailure);
}

function resolveFailure(jqXhr) { 
  // return whatever you want here. I added the status in case that is of interest
  // could return `false` or string or whatever
  // can also log any issues back to server if needed
  return {
    error: true,
    status: jqXhr.status,
    statusText: jqXhr.statusText
  };
}

var req = ajax1('https://api.myjson.com/bins/l9ywp'),
    req2 = ajax1('https://httpbin.org/FAIL'),
    req3 = ajax1('https://api.myjson.com/bins/l9ywp');

// could also replace `$.when with `Promise.all()`
$.when(req, req2, req3).then(function(r1, r2, r3) {
  // validate the arguments based on whatever you return in the catch()
  console.log('r1', r1);
  console.log('r2', r2);// object returned from catch()
  console.log('r3', r3);
});
.as-console-wrapper {max-height: 100%!important;top:0}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

【讨论】:

  • 非常感谢!这就是我要的。一个问题,.then(data => data) 是否需要在ajax1() 中?语法似乎不对。
  • 箭头函数语法等价于then(function(data){ return data})。您想在$.when 中看到什么取决于您。如果您使用Promise.all() 而不是$.when,则只有数据会在没有该步骤的情况下显示
【解决方案2】:

不要从$.when() 调用done(),而是像这样尝试then()

https://jsfiddle.net/L83ny70k/

在 JSFiddle 中检查您的控制台以查看失败请求的响应!

JQuery 的when().then() 可以有两个函数,第一个函数会在所有请求都解决时触发,类似于done() 的工作方式,第二个函数会在任何请求失败时触发,并将失败请求的响应传递给你的函数,所以你可以用它做你想做的事!

希望有帮助:)

更多信息

https://api.jquery.com/jquery.when/

https://api.jquery.com/deferred.then/

编辑:此解决方案将阻止您访问所有其他成功请求的响应。感谢您指出@charlietfl!

【讨论】:

  • 谢谢。但是,onSuccess console.log 没有触发?
  • @SergiuTripon 它不会出于同样的原因,您的原始代码不会
  • @charlietfl,不确定您的意思...但是如果您将 url2 更改为与 url1 相同的内容,它肯定会起作用,因此它实际上不会失败。
  • 但是 OP 不希望一个请求失败阻止访问其他请求的成功。仔细阅读问题。换句话说...无论请求的状态如何,您的 onError 都不应触发
  • 同意措辞有点笨拙,但请继续阅读有关访问 a2 的信息,无论是否为 404 并且也能够访问良好的请求
【解决方案3】:

$.when() documentation 的最后一点可能对您有所帮助:

当两个ajax请求都成功时执行函数myFunc,或者 如果其中一个有错误,则 myFailure。

例子:

$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) )
  .then( myFunc, myFailure );

现在,如果你想知道单个调用的失败,你还可以获取每个调用的单个状态码,这样一个调用就像:

function ajax2(url) {
    return $.ajax({
        url: url
    });
}

可以转换成类似的东西:

function ajax2(url) {
    var isGoodResponse = $.ajax(url).always(function(xhr){
         console.log(xhr);
         // do whatever checks you want here
         return xhr.statusCode === '404';
    });
    // returns true/false
    return isGoodResponse;
}

例如:

$.ajax("http://false-url.duh")
    .always(function(xhr){
        console.log(xhr);
    }
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

【讨论】:

  • 看不出这是如何回答 OP 问题的。 Op 想要它,所以无论状态如何,myFunc 总是会触发,而 myFailure 永远不会触发
猜你喜欢
  • 2012-04-20
  • 1970-01-01
  • 2012-02-25
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多