Fetch API 并不是新知识了,大多数开发人员都曾在某些时候使用它来发送请求,但是我们真的知道使用此 API 时如何处理错误吗?
在下面的代码中,使用 Fetch API 发送请求时返回 404 错误,控制台中的消息是什么:成功还是失败?
try {
// 返回404
const response = await fetch('https://xxxx');
console.log('Success');
} catch {
console.error('Failed');
}
如果我们假设此代码在发生 404 错误时打印的是 Failed,那么我们可能需要认真看一下这篇文章了,因为我们的答案是错误的。console.log在控制台打印的是 Success,下文将阐述原因以及使用 Fetch API 处理错误的最佳方法是什么。
简而言之,Fetch 是一个用于向服务器发出异步 HTTP GET 和 POST 请求的一个 API。
使用 Fetch API 时可能会出现不同的错误,例如:服务器错误(500)、未找到错误(404)、网络错误、CORS 错误等。我们有不同的方法来处理所有这些错误,如下所示。
假设我们熟悉 JavaScript 中的 Promise 并知道它们是如何工作的(因为 Fetch API 如此受欢迎的原因之一是它返回一个 Promise)。因此,我们可以使用 then、catch、finally 这些方法来处理成功、拒绝和完成时的结果。
将 fetch 调用包装在 try/catch 块中是处理错误的一种非常常见的方法(请参见下面的示例),但并非所有错误都可以捕获,我们将在代码后面对此进行解释。
try {
// 假如下面的接口会出现cors错误
const response = await fetch('https://xxxx');
} catch {
console.error('Failed');
}
// Failed
此代码将尝试执行获取并仅在 Promise 被拒绝时捕获到错误(这可能发生在两种情况下):
对于服务器状态错误(例如 404 和 500),fetch 将返回 resolve 的状态,这就是为什么 catch 无法在本文开头的示例中获取它们的原因。
使用 Fetch API 处理错误的另一种常见方法是在 Promise 解析时检查响应状态。
// 假设这个接口返回404
const response = await fetch('https://xxxx');
if (response.ok) {
// ...
} else {
console.error('Failed');
}
这里我们用来 response.ok 来检查响应是否成功(true 或 false)。
当状态码在200到299之间时, response.ok为ok(表示成功)。
当服务器返回上述以外的任何其他状态时,response.ok为false。示例包括 404(未找到)和 500(内部服务器错误)。
正如我们在上面看到的,try/catch 和 try/catchresponse.ok 用于捕获不同类型的错误,因此我们可以结合这两种方法,使用 Fetch API 更好地处理错误。请参阅下面的示例:
try {
const response = await fetch('https://xxx');
if (response.ok) {
console.log('Promise resolved and HTTP status is successful');
// ...
} else {
console.error('Promise resolved but HTTP status failed');
}
} catch {
console.error('Promise rejected');
}
解释:
处理 try 块内错误的另一种常见方法是在 response.ok 不是 true 时抛出错误,以使 catch 块被执行,以便我们可以在同一位置处理所有错误。请参阅下面的示例以更好地理解:
try {
const response = await fetch('https://restcountries.com/v4.1/all');
if (response.ok) {
console.log('Promise resolved and HTTP status is successful');
// ...
} else {
if (response.status === 404) throw new Error('404, Not found');
if (response.status === 500) throw new Error('500, internal server error');
throw new Error(response.status);
}
} catch (error) {
console.error('Fetch', error);
// "Fetch Error: 404, Not found"
}
在这里,我们抛出错误以在 catch 块中处理它们,并根据错误类型在控制台中显示自定义消息。