贝利信息

如何在javascript中发起网络请求_从Fetch API到Axios的最佳实践【教程】

日期:2026-01-16 00:00 / 作者:狼影
应根据项目需求选择 Fetch 或 Axios:Fetch 轻量现代但需手动处理错误、超时和取消;Axios 提供拦截器、自动 JSON 解析等便利功能,但增加依赖。关键在统一错误分类与状态管理。

Fetch API 是现代浏览器发起网络请求的原生方案,但直接使用它容易忽略错误处理、超时控制和请求取消等关键问题;Axios 提供了更友好的默认行为和可扩展能力,但引入额外依赖需权衡。是否用 Axios,取决于你是否需要拦截器、自动 JSON 解析、取消请求或 IE 兼容性支持。

Fetch API 的常见陷阱与修复写法

原生 fetch() 不会因 HTTP 状态码(如 404、500)抛出错误,response.ok 必须手动检查;同时它不支持超时,且无法中止正在进行的请求(除非用 AbortController)。

const controller = new AbortController();
setTimeout(() => controller.abort(), 8000);

try {
  const res = await fetch('/api/data', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ id: 123 }),
    signal: controller.signal,
    credentials: 'include'
  });

  if (!res.ok) throw new Error(`HTTP ${res.status}`);

  const data = await res.json();
} catch (err) {
  if (err.name === 'AbortError') console.log('请求已超时或取消');
  else console.error('请求失败:', err);
}

Axios 的配置要点与默认行为差异

Axios 默认自动解析 JSON 响应体,但默认不携带 cookies(withCredentials: false),且响应结构是包裹式的 response.data,不是裸数据。它的拦截器非常实用,但要注意:请求拦截器中修改 config.url 后,baseURL 不再生效。

axios.defaults.withCredentials = true;

axios.interceptors.request.use(config => {
  config.headers.Authorization = `Bearer ${getToken()}`;
  return config;
});

axios.interceptors.response.use(
  res => res.data, // 统一提取 data
  err => {
    if (err.response?.status === 401) logout();
    return Promise.reject(err);
  }
);

何时该坚持用 Fetch,而非引入 Axio

s

项目已用 ESM 按需加载、目标环境为现代浏览器(Chrome 62+/Firefox 57+)、团队倾向最小依赖、且不需要请求重试或复杂拦截逻辑时,Fetch 更轻量可控。尤其在 Service Worker 或 Deno 环境中,Axios 并不适用。

并发请求与错误聚合的实际处理方式

无论是 Promise.all() 还是 axios.all(),任一请求失败都会导致整个集合 reject。真实场景中往往需要“尽力而为”——即返回所有结果(含错误),而不是中断全部。

const requests = ids.map(id =>
  fetch(`/api/user/${id}`).then(r => r.json()).catch(err => ({ error: err.message }))
);

const results = await Promise.allSettled(requests);
const successes = results.filter(r => r.status === 'fulfilled').map(r => r.value);
const failures = results.filter(r => r.status === 'rejected').map(r => r.reason);

真正麻烦的不是选 Fetch 还是 Axios,而是统一错误分类(网络层?业务层?认证失效?)、标准化 loading 状态管理、以及让 timeout 和 abort 行为在 UI 上可感知 —— 这些几乎从不在库文档里写清楚,却直接影响调试效率。