17370845950

如何在JavaScript中与后端API进行数据交互_Fetch与Axios详细对比指南【教程】
日常开发优先用 axios;fetch 默认 credentials 为 'omit'(不带 Cookie),axios 为 'same-origin'(同源自动带);fetch 对 4xx/5xx 不自动报错,需手动判断 res.ok,axios 默认抛错。

直接说结论:日常开发中优先用 axios,除非你明确需要轻量、无依赖或必须用原生 fetch 的场景(比如写浏览器扩展、做 polyfill、或团队强制规范)。

为什么 fetch 默认不带 Cookie,而 axios 默认带?

fetch 默认的 credentials 选项是 'omit',即不发送 Cookie 和认证头;axios 默认是 'same-origin'(同源时自动携带 Cookie)。这是最常踩的坑——登录态丢失、401 报错、接口返回空数据。

  • 修复 fetch:调用时必须显式加 { credentials: 'include' }
  • 修复 axios:跨域需后端配合设置 Access-Control-Allow-Credentials: true,且不能设 Access-Control-Allow-Origin: *(必须指定具体域名)
  • 注意:即使加了 credentials: 'include',若后端没返回正确的 CORS 头,浏览器仍会静默拦截响应

如何统一处理 4xx/5xx 响应,而不是手动检查 status?

fetch 只在真正网络失败(如断网、DNS 错误)时 reject,HTTP 状态码 400、500 等仍算 “success”,需手动判断;axios 默认对非 2xx 状态码抛错,可直接进 catch

fetch('/api/user')
  .then(res => {
    

if (!res.ok) throw new Error(`${res.status} ${res.statusText}`); return res.json(); }) .catch(err => console.error('请求失败:', err));
axios.get('/api/user')
  .catch(err => {
    // 400、500、网络错误都会进这里
    console.error('请求失败:', err.response?.status, err.message);
  });
  • fetchres.ok 等价于 res.status >= 200 && res.status
  • axioserr.response 包含响应体,err.request 是原始 XMLHttpRequest / fetch Request 对象,err.message 描述错误类型
  • 想让 fetch 行为接近 axios,建议封装一层,自动检查 res.okthrow

上传文件时 FormData 处理差异

两者都支持 FormData,但默认行为不同:fetch 不会自动设置 Content-Type 请求头(浏览器会自动设为 multipart/form-data; boundary=...);axios 若传入 FormData,会删掉你手动设的 Content-Type(避免冲突),由浏览器自动生成。

  • fetch 上传时,**不要手动设置 Content-Type 头**,否则边界符失效,后端收不到字段
  • axios 上传时,也别设 Content-Type,它内部已处理;若强行设成 'multipart/form-data'(不带 boundary),后端大概率解析失败
  • 进度监听:fetch 需靠 ReadableStream + progress 事件(兼容性差);axios 原生支持 onUploadProgress 配置项

真正麻烦的不是选哪个库,而是混用时的隐性不一致:比如一个项目里部分用 fetch 封装了 request,部分用 axios,结果 401 处理逻辑分散、超时配置两套、错误消息格式不统一。选一个,配好拦截器/封装层,比反复纠结语法细节重要得多。