【问题标题】:fetch resolves even if 404?fetch 即使 404 也能解决?
【发布时间】:2017-01-10 20:41:07
【问题描述】:

使用此代码:

fetch('notExists') // <---- notice 
    .then(
        function(response)
        {
           alert(response.status)
        }
    )
    .catch(function(err)
    {
       alert('Fetch Error : ', err);
    });

这个承诺解决

mdn

它返回一个可以解析为该请求的响应的承诺, 不管成功与否。

一个失败的 ajax 请求即使转到一个不存在的资源也得到了解决,这不是很奇怪吗?

我的意思是——接下来呢?将fetch 发送到已关闭但仍获得已解决承诺的服务器?

我知道我可以在 response 对象的 ok 属性上进行调查,但仍然 -

问题

为什么会为完全错误的请求(非现有资源)解决提取问题。

BTW , jquery request , does get rejected

【问题讨论】:

  • 它必须解决才能处理错误代码。
  • @Barmar 那么为什么不在 catch/reject 处理程序上呢?
  • 您希望获取标准的作者回复吗?因为他们将是那些无需猜测就能回答这个问题的人。
  • @MikeMcCaughan 我只是想找到答案。我不希望 Henrik 在这里回答 :-)
  • 我同意,404 不走错误路径是疯狂的。

标签: javascript promise fetch


【解决方案1】:

拒绝处理程序用于网络和 CORS 错误 iirc。如果请求到达服务器并以有效的 http 响应进行响应,则即使响应代码为 4xx 或 5xx,promise 也会得到满足。

【讨论】:

    【解决方案2】:

    fetch() 调用仅在网络请求本身因某种原因失败(未找到主机、未连接、服务器未响应等...)时才会被拒绝。

    从承诺的角度来看,从服务器返回的任何结果(404、500 等...)都被视为成功请求。从概念上讲,您从服务器发出请求,服务器响应您,因此从网络的角度来看,请求成功完成。

    然后您需要测试该成功响应以查看是否有您想要的答案类型。如果您希望 404 被拒绝,您可以自己编写代码:

    fetch('notExists').then(function(response) {
        if (!response.ok) {
            // make the promise be rejected if we didn't get a 2xx response
            const err = new Error("Not 2xx response");
            err.response = response;
            throw err;
        } else {
             // go the desired response
        }
    }).catch(function(err) {
        // some error here
    });
    

    您甚至可以创建自己的 myFetch(),它会自动为您执行此操作(将任何非 200 响应状态转换为拒绝)。

    已解决的承诺背后的原因是什么? 请求(非现有资源/服务器停机)。

    首先,服务器关闭不会产生成功的响应 - 会拒绝。

    如果您成功连接到服务器,向其发送请求并返回响应(任何响应),则会生成成功响应。至于“为什么”fetch() 界面的设计者决定以此为由拒绝,如果不与实际参与该界面设计的人交谈,就很难说,但对我来说这似乎是合乎逻辑的。通过这种方式,拒绝会告诉您请求是否通过并得到有效响应。由您的代码决定如何处理响应。当然,您可以创建自己的包装函数来修改默认行为。

    【讨论】:

    • 哦,好吧,我知道没有地方可以比较,但 $.ajax//a 确实被拒绝了。 jsbin.com/pukurolego/1/edit?html,js,output
    • @RoyiNamir - 我不认为你是 jsbin 的例子正在做你认为的事情。如果我console.log() 拒绝错误,我会看到这个Failed to load resource: net::ERR_ADDRESS_UNREACHABLE http://0.0.0.22/。我不确切知道 jQuery 的行为方式,但你的 jsbin 没有测试正确的东西。
    • 你说得对,我的错,没看到。我需要休息。
    【解决方案3】:

    使用此代码...

    fetch(`https://fercarvo.github.io/apps/integradora/DB/corpus.json`)
    .then(async (data) => {
        if (data.ok) {
            data = await data.json()
            //Here you have your data...
        }
    }).catch(e => console.log('Connection error', e))
    

    【讨论】:

      【解决方案4】:

      以@fernando-caravajal 示例为基础(这对我来说更容易用于异步/等待),我在下面制作了这个稍作修改的版本,用于发布查询,并发送了参数。我添加了throw new Error 语句,因为我无法捕捉到response.ok == false 上的故障。

      /**
       *  Generic fetch function
       */
      function fetchData(url,parameters,callback) {
      
        fetch(url,{
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(parameters),
        })
        .then(async(response) => {
            // status 404 or 500 will set ok to false
            if (response.ok) {
                // Success: convert data received & run callback
                result = await response.json();
                callback(result);
            }
            else {
                throw new Error(response.status + " Failed Fetch ");
            }
        }).catch(e => console.error('EXCEPTION: ', e))
      }
      

      【讨论】:

        【解决方案5】:

        正如其他人所说, fetch 仅在出现适当的网络问题时才返回错误。 “down”服务器不会返回 4XX,它不会返回任何内容或 5XX,具体取决于它是如何“down”的。 我倾向于使用 axios 而不是 fetch 主要是因为这个问题让我编写了更多代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-03-12
          • 2016-04-14
          • 1970-01-01
          • 1970-01-01
          • 2021-08-10
          • 2020-05-31
          相关资源
          最近更新 更多