fetch是当前标准方案,但需手动处理错误、超时和取消:默认不报404/500错误,须检查response.ok;超时需AbortController+setTimeout;axios适合需自动JSON处理、拦截器或IE11兼容的场景。

JavaScript 做网络请求,fetch 是当前标准方案,XMLHttpRequest 已不推荐新项目使用。但直接写 fetch 容易忽略错误处理、超时、取消等关键点,导致请求“看似发了,实则失败静默”。
为什么 fetch 默认不报错 404 / 500?
fetch 只在网络层失败(如断网、DNS 失败、CORS 拒绝)时才 reject;HTTP 状态码如 404、500 仍算“成功”,response.ok 才是判断业务是否成功的依据。
- 必须手动检查
response.ok === false或response.status >= 400 -
await response.json()会在响应体非合法 JSON 时抛出语法错误,需额外 try/catch - 不检查状态直接解构数据,很可能得到
undefined或解析异常
const res = await fetch('/api/user');
if (!res.ok) {
throw new Error(`HTTP ${res.status}: ${res.statusText}`);
}
const data = await res.json(); // 这里才可能因 JSON 格式问题 throw
如何安全地设置超时和取消请求?
fetch 本身不支持超时,也不原生支持取消(AbortController 是唯一标准方式)。没加超时的请求可能卡死 UI 或积压 pending 请求。
- 用
AbortController实现取消:调用controller.abort()后,fetch立即 reject 并抛出AbortError - 超时必须靠
setTimeout+AbortController组合实现,不能只靠Promise.race包裹fetch - 注意:
AbortController在旧版 Safari(fetch 的支持不完整,需确认目标环境
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 8000);
try {
const res = await fetch('/api/data', { signal: controller.signal });
clearTimeout(timeoutId);
return res.json();
} catch (err) {
if (err.name === 'AbortError') throw new Error('Request timed out');
throw err;
}
什么时候该用 axios 而不是原生 fetch?
如果你需要自动序列化/反序列化 JSON、统一错误拦截、请求/响应拦截器、自动重试、或兼容 IE11,axios 是更省心的选择。但它的体积(约 5 kB gzip)和隐式行为(比如默认加 Content-Type: application/json)也可能带来意外。
免费 盛世企业网站管理系统(SnSee)系统完全免费使用,无任何功能模块使用限制,在使用过程中如遇到相关问题可以去官方论坛参与讨论。开源 系统Web代码完全开源,在您使用过程中可以根据自已实际情况加以调整或修改,完全可以满足您的需求。强大且灵活 独创的多语言功能,可以直接在后台自由设定语言版本,其语言版本不限数量,可根据自已需要进行任意设置;系统各模块可在后台自由设置及开启;强大且适用的后台管理支
立即学习“Java免费学习笔记(深入)”;
-
axios默认把4xx/5xx状态转为 rejected Promise,不用手动检查response.ok - 它会自动把请求体对象转成 JSON 字符串,并设
Content-Type;若需发送表单数据,得显式用FormData或设headers - 拦截器里修改
config.url或config.data是常见需求,fetch需要封装函数才能做到类似效果
axios.get('/api/users', {
timeout: 10000,
headers: { 'X-Trace-ID': 'abc123' }
}).catch(err => {
if (axios.isCancel(err)) console.log('Request canceled');
});
真正难的不是发请求,而是让每个请求都可观察、可中断、可重试、失败时有明确归因。别让一个没 catch 的 fetch 拖垮整个页面的状态一致性。









