javascript fetch解析即使404?

tez616oj  于 2023-06-28  发布在  Java
关注(0)|答案(6)|浏览(156)

使用此代码:

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

这个承诺 * 解决 *。
mdn
它返回一个promise,该promise解析为该请求的Response,无论它是否成功。
一个失败的 AJAX 请求被解析,即使它去了一个不存在的资源,这不是很奇怪吗?
我是说-接下来呢?一个fetch到一个已经停机的服务器,仍然得到一个已解析的promise?
我知道我可以在response对象的ok属性上进行调查,但仍然-

问题

为什么一个fetch会被解析为一个完全错误的请求(不存在的资源)。
BTW , jquery request , does get rejected

bvuwiixz

bvuwiixz1#

fetch()调用仅在网络请求本身因某种原因失败时才会被拒绝(主机未找到、没有连接、服务器未响应等)。
从承诺的Angular 来看,从服务器(404、500等)返回的任何结果都被认为是成功的请求。从概念上讲,您向服务器发出请求,服务器回答您,因此从网络的Angular 来看,请求成功完成。
然后,您需要测试成功的响应,看看是否有您想要的答案类型。如果你想让404成为拒绝,你可以自己编写代码:

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

您甚至可以自己制作myFetch(),它会自动为您执行此操作(将任何非200响应状态转换为拒绝)。
对于一个完全错误的请求(不存在的资源/服务器关闭),解析的promise背后的原因是什么?
首先,服务器停机不会生成成功的响应-这将拒绝。
如果您成功连接到服务器,向其发送请求并且它返回响应(任何响应),则会生成成功的响应。至于“为什么”fetch()接口的设计者决定基于此拒绝,如果不与实际参与该接口设计的人交谈,这有点难以启齿,但对我来说似乎是合乎逻辑的。通过这种方式,拒绝告诉您请求是否通过并得到有效的响应。由您的代码决定如何处理响应。当然,您可以创建自己的 Package 器函数来修改默认行为。

r1zk6ea1

r1zk6ea12#

使用此代码...

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

stszievb3#

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

uxhixvfz

uxhixvfz4#

在@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))
}
p8h8hvxi

p8h8hvxi5#

对于喜欢使用awaittry catch的人,假设有两个服务器场景:
1.成功200调用将返回

{
  "user": "1234",
  "token": "1231411acad..."
}

1.404调用失败将返回

{
  "error": "There was an error"
}

在你的客户端JS中,你可以像这样处理它:

try {
  const {user, token, error} = await fetch('API_URL', {
    method: "POST",
     headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ ... }),
  }).then((response) => response.json());

  if (error) throw new Error(error);

  // Continue successful logic here...
} catch (error) {
  console.log(error);
  // Continue failed logic here...
}
aurhwmvo

aurhwmvo6#

正如其他人所说,fetch只在适当的网络问题的情况下返回错误。一个“down”服务器不会返回4XX,它将什么也不返回或5XX取决于它是如何“down”的。我倾向于使用axios而不是fetch,主要是因为这个问题让我写了更多的代码。

相关问题