fetch 即使 404 也解析?

fetch resolves even if 404?

使用此代码:

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

此承诺解决

mdn

It returns a promise that resolves to the Response to that request, whether it is successful or not.

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

我的意思是 - 下一步是什么? fetch 到服务器,该服务器已关闭但仍能得到已解决的承诺?

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

问题

为什么对于一个完全错误的请求(不存在的资源),提取得到解决。

BTW , jquery request , does get rejected

拒绝处理程序用于网络和 CORS 错误 iirc。如果请求到达服务器并且它以有效的 http 响应进行响应,则承诺得到履行,即使响应是代码 4xx 或 5xx。

只有当网络请求本身由于某种原因(找不到主机、没有连接、服务器没有响应等)而失败时,才会拒绝 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 {
         // got the desired response
    }
}).catch(function(err) {
    // some error here
});

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

What is the reason behind a resolved promise for a a completely bad request ( non existing resource / server down).

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

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

使用此代码...

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))

基于@fernando-caravajal 示例(这对我来说更容易使用 async/await)我在下面做了这个稍微修改的版本,用于 post 查询,发送了参数。我添加了 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))
}

正如其他人所说,如果出现适当的网络问题,只获取 returns 错误。 “宕机”服务器不会 return 4XX,它会 return 什么都没有或 5XX 取决于它是如何“宕机”的。 我倾向于使用 axios 而不是 fetch 主要是因为这个问题让我写了更多的代码。