fetch 不会因 4xx/5xx 状态码自动报错,仅网络失败时 reject;需手动检查 response.ok 或 status 处理业务错误,并注意 json 解析异常。

Fetch 不会因为 HTTP 状态码是 4xx 或 5xx 而自动抛出错误,它只在**网络失败**(如断网、DNS 失败、请求被阻止)时 reject。所以 response.status 为 400、404、500 等属于“响应成功但业务失败”,需手动判断处理。
检查 response.ok 属性(最简洁方式)
response.ok 是一个布尔值,等价于 response.status >= 200 && response.status 。这是官方推荐的快速判断方式:
- ✅ 推荐用于大多数场景,语义清晰、写法简洁
- ❌ 注意:304(Not Modified)也返回
true,如果业务上需要区分缓存响应,需额外检查status
示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
fetch('/api/user')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status = ${response.status}`);
}
return response.json();
})
.catch(err => console.error('请求失败:', err));
显式检查 status 码范围(更精细控制)
当需要对不同状态码做差异化处理(比如 401 跳登录、403 提示无权限、429 限流重试),可直接读取 response.status:
- ⚠️ 注意:必须在调用
response.json()、response.text()等方法之前检查 status,否则可能因解析失败掩盖原始错误 - ? 可配合
response.statusText获取状态文本(如 "Not Found")增强提示
示例:
fetch('/api/data')
.then(response => {
switch (response.status) {
case 401:
window.location.href = '/login';
break;
case 403:
alert('权限不足');
break;
case 429:
alert('操作太频繁,请稍后再试');
break;
default:
if (!response.ok) throw new Error(`${response.status} ${response.statusText}`);
return response.json();
}
});
封装成可复用的 fetch 工具函数
避免每个请求都重复写状态判断,建议封装一层:
- ✅ 统一错误分类(网络错误 / HTTP 错误 / 解析错误)
- ✅ 支持自定义 4xx/5xx 的处理逻辑(如自动刷新 token)
- ✅ 返回 Promise 结构,便于后续扩展
简化版示例:
async function safeFetch(url, options = {}) {
try {
const response = await fetch(url, options);
if (!response.ok) {
const error = new Error(`${response.status} ${response.statusText}`);
error.response = response;
throw error;
}
return response;
} catch (err) {
if (err.name === 'TypeError' && err.message.includes('fetch')) {
err.message = '网络连接异常,请检查网络';
}
throw err;
}
}
// 使用
safeFetch('/api/profile')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err.message));
注意 JSON 解析失败也会抛错(常被忽略)
即使 response.ok === true,若后端返回非 JSON 内容(如 HTML 错误页、空响应、格式错误 JSON),response.json() 仍会 reject:
- ✅ 建议用
try/catch包裹解析步骤,或用.catch()捕获解析异常 - ? 可先用
response.headers.get('content-type')判断是否含application/json再解析
示例:
fetch('/api/data')
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json().catch(() => {
throw new Error('响应数据格式错误,无法解析为 JSON');
});
})Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










