fetch对网络连接失败会直接reject promise进入.catch(),而http状态码错误(如404、500)仍resolve需手动检查response.ok;前者错误类型为typeerror,后者需在首个.then()中判断并throw统一处理。

Fetch 对网络连接失败和服务器报错的处理方式完全不同——前者会直接 reject Promise,进 .catch();后者(如 404、500)仍 resolve,必须手动检查 response 状态。
网络连接失败:自动进入 catch
这类错误发生在请求根本没发出去或中途断开时,比如:断网、域名无法解析、跨域被拦截、服务地址不存在、SSL 证书问题等。fetch 会立即 reject,Promise 链直接跳到 .catch() 块。
- 错误对象通常是 TypeError,message 常含 "Failed to fetch" 或 "NetworkError"
- 此时 response 对象根本不会生成,所以不能访问 response.status 或 response.ok
- 常见于本地开发时后端未启动、生产环境 DNS 故障、用户关闭 Wi-Fi 等场景
HTTP 状态码错误:需手动判断并抛出
只要服务器返回了 HTTP 响应(哪怕状态码是 400、401、404、500),fetch 就认为“请求成功完成”,Promise 正常 resolve,并把 Response 实例传给第一个 .then()。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 必须检查 response.ok(等价于 status 在 200–299)或 response.status
- 若不检查,后续 .then() 仍会执行,可能因解析空/错误响应体而报错(如 JSON.parse 失败)
- 推荐在第一个 .then() 中主动 throw 错误,让逻辑统一走 .catch(),便于集中处理
如何统一捕获两类错误
关键是在 Promise 链中分两层拦截:第一层处理 HTTP 级错误,第二层兜底网络级异常。
- 在首个 .then() 中判断 if (!response.ok),然后 throw new Error(`${response.status} ${response.statusText}`)
- 用 response.json() 或 response.text() 获取响应体前,确保已确认 response.ok,否则可能解析失败
- 如果后端返回结构化错误(如 { code: 40001, message: "用户名已存在" }),应在 throw 前 await response.json(),再构造带业务信息的错误
- .catch() 中可区分错误类型:用 error instanceof TypeError 判断是否为网络问题;否则视为业务或服务端错误
实际代码示例
下面是一个兼顾两者、能提取自定义错误消息的写法:
fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: 'a@b.com', pwd: '123' })
})
.then(async response => {
if (!response.ok) {
// 先尝试读取后端返回的 JSON 错误体
try {
const errorData = await response.json();
throw new Error(errorData.message || `${response.status} ${response.statusText}`);
} catch (e) {
// 若不是 JSON,退回到标准提示
throw new Error(`${response.status} ${response.statusText}`);
}
}
return response.json();
})
.catch(error => {
if (error instanceof TypeError && error.message.includes('fetch')) {
console.error('网络异常,请检查网络连接');
} else {
console.error('接口报错:', error.message);
}
});Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










