跳到正文

目录

Axios:Promise HTTP 客户端完全指南

Axios:Promise HTTP 客户端完全指南

快速信息卡

  • GitHub: axios/axios
  • Stars: 109k+
  • Forks: 11.8k+
  • License: MIT
  • 语言: JavaScript/TypeScript
  • 最后更新: 2026-09-08

阅读地图

适合已经有 JavaScript 基础、会用 async/await 的读者。读完后你应该能独立完成下列事情:跑通一次 GET 与 POST 请求;用一个 axios.create 实例收敛 baseURL 与超时;通过拦截器统一注入请求头并归一错误;用 AbortController 在页面切换或超时时取消请求;最后把这一套封装成一个可直接接入项目、带重试和监控的客户端。


一、项目概述

Axios 是什么

Axios 是一个基于 Promise 的 HTTP 客户端,走一套同时跑在浏览器和 Node.js 的 API。它没有带来新的网络概念,更多是把你常写的那段"发请求、等响应、判错误、拆数据"样板代码收拢进库,再用拦截器、实例和超时这些约定把重复逻辑抽走。它的价值几乎都落在"省包装"上:用 fetch 得自己封装错误判断和拦截,而 Axios 把这些写进了库本身。

官方网站https://axios-http.com 官方文档https://axios.rest(2026 年起,axios-http.com/docs 已整体迁移并重定向到新文档站) GitHub 仓库https://github.com/axios/axios

主要特性

特性说明
浏览器请求从浏览器使用 XMLHttpRequest 发送请求
Node.js 请求在 Node.js 环境中发送 http 请求
Promise API完整支持 Promise API,async/await 友好
拦截器拦截请求和响应,可添加自定义逻辑
数据转换自动转换请求和响应数据
请求取消支持使用 AbortController 取消请求
自动 JSON 处理自动序列化/解析 JSON 数据
表单序列化支持 application/x-www-form-urlencoded 和 multipart/form-data
XSRF 防护内置跨站请求伪造防护机制

仓库统计

指标数值(2026-09-08)
GitHub Stars109.2k
Forks11.8k
Open Issues88(GitHub API 口径,含 PR)
最新版本1.20.0(npm latest)
默认分支v1.x
许可证MIT

Axios vs fetch API

对比项Axiosfetch API
JSON 自动处理✅ 自动❌ 需要手动调用 .json()
请求取消✅ 简单易用⚠️ AbortController(较复杂)
超时控制✅ 内置 timeout 配置❌ 需要额外实现
拦截器✅ 简洁易用❌ 需要包装 fetch
错误处理✅ 统一处理 4xx/5xx⚠️ 仅在网络错误时 reject
浏览器兼容✅ 广泛兼容⚠️ 现代浏览器
请求/响应转换✅ 易于配置❌ 需要手动处理

什么时候优先选 Axios

如果业务里常见"同一个 baseURL、统一加请求头、统一处理 4xx/5xx、控制超时"这类重复逻辑,Axios 的实例、拦截器和 AxiosError 分层判断能少写不少样板;这类需求出现得越多,省下的代码越明显。反过来,如果项目对依赖数量很敏感,或只是偶尔发一两个基础请求,原生 fetch 加上一两个小封装就够,不必为这些场景引入一个库。


二、安装与环境配置

支持的环境

浏览器支持:Chrome、Firefox、Safari、Opera、Edge(最新版)

Node.js 环境:跟随当前活跃的 Node.js 发布线,具体兼容范围以各版本发布说明为准。

安装方式

使用 npm

npm install axios

使用 yarn

yarn add axios

使用 pnpm

pnpm add axios

使用 bun

bun add axios

使用 bower(已过时):

bower install axios

CDN 引入

使用 jsDelivr(推荐)

<script src="https://cdn.jsdelivr.net/npm/axios@1/dist/axios.min.js"></script>

使用 unpkg

<script src="https://unpkg.com/axios@1/dist/axios.min.js"></script>

上面的 @1 会始终解析到当前最新的 1.x 版本。若想锁定某个具体稳定版,把 @1 换成对应版本号即可,例如 axios@1.7.7

ESM 导入方式

现代 ES6 导入

import axios, { isCancel, AxiosError } from 'axios';

默认导出方式

import axios from 'axios';
console.log(axios.isCancel('something'));

CommonJS 导入(Node.js 传统方式):

const axios = require('axios');
console.log(axios.isCancel('something'));

三、基本使用

GET 请求

基础 GET 请求

import axios from 'axios';

try {
  const response = await axios.get('/user?ID=12345');
  console.log(response);
} catch (error) {
  console.error(error);
}

带参数的 GET 请求

const response = await axios.get('/user', {
  params: {
    ID: 12345,
    name: 'John'
  }
});

POST 请求

基础 POST 请求

const response = await axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
});
console.log(response);

并发请求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

Promise.all([getUserAccount(), getUserPermissions()])
  .then(function (results) {
    const acct = results[0];
    const perm = results[1];
    console.log('Account:', acct);
    console.log('Permissions:', perm);
  });

async/await 用法

async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

getUser();

注意:async/await 是 ECMAScript 2017 的一部分,Internet Explorer 和旧版浏览器不支持,使用时需注意兼容性。

理解 response 对象

Axios 请求成功时 resolve 的不是裸数据,而是一个 response 对象,最常用的三个字段是 datastatusheaders

字段说明
data服务端返回的响应体,JSON 已自动解析成对象或数组
statusHTTP 状态码,如 200、404
statusText状态文本,如 OK
headers响应头对象,键名统一为小写
config本次请求实际使用的配置对象
request底层请求对象(浏览器是 XMLHttpRequest,Node.js 是 ClientRequest)

所以取数据时要写 response.data,而不是 response 本身。如果嫌每个调用点都多一层 .data 麻烦,可以在响应拦截器里先剥掉外壳:

// 全局生效
axios.interceptors.response.use(response => response.data);

若你用的是上一节创建的实例,把拦截器注册在实例上,只影响该实例的请求:

const apiClient = axios.create({ baseURL: 'https://api.example.com' });
apiClient.interceptors.response.use(response => response.data);

之后业务代码拿到的就是解析后的数据:

const users = await apiClient.get('/users'); // users 直接是数组

四、Axios API 详解

请求方式

Axios 提供了多种请求方式:

// 通用请求方式
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

// GET 请求
axios.get('/user/12345');

// POST 请求
axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
});

// DELETE 请求
axios.delete('/user/12345');

// PUT 请求
axios.put('/user/12345', {
  firstName: 'Fred'
});

// PATCH 请求
axios.patch('/user/12345', {
  firstName: 'Fred'
});

// HEAD 请求
axios.head('/user/12345');

// OPTIONS 请求
axios.options('/user/12345');

请求配置

常用配置项

const response = await axios({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  headers: {
    'X-Custom-Header': 'foobar',
    'Content-Type': 'application/json'
  },
  params: {
    ID: 12345
  },
  auth: {
    username: 'admin',
    password: 'secret'
  }
});

配置项详解

配置项类型说明
urlstring请求 URL,必填
methodstring请求方法,默认为 GET
baseURLstring基础 URL,将自动拼接在 url 前
timeoutnumber超时时间(毫秒),默认为 0(无超时)
headersobject自定义请求头
paramsobjectURL 参数,会自动序列化为 ?key=value
dataany请求体数据
authobjectHTTP Basic 认证 {username, password}
responseTypestring响应类型:json/blob/document/stream/text
withCredentialsboolean是否携带跨域 cookies
validateStatusfunction定义哪些状态码算成功,返回 false 时拒绝该请求
maxContentLengthnumber响应体体积上限(字节),超限直接抛错
maxBodyLengthnumber请求体体积上限(字节),主要用于 Node.js
onDownloadProgressfunction下载进度回调
xsrfCookieNamestringXSRF token 读取的 cookie 名,默认 XSRF-TOKEN
xsrfHeaderNamestringXSRF token 写入的请求头名,默认 X-XSRF-TOKEN

validateStatus 默认是「200-299 都算成功」,想放宽或收紧就覆盖它,例如把 304 也归入成功:

const resp = await axios.get('/page', {
  validateStatus: (status) => status >= 200 && status < 300 || status === 304
});

responseType 若设为 stream,只在 Node.js 环境生效;浏览器端可选值受 XMLHttpRequest 限制,只有 jsontextblobarraybufferdocument

XSRF 防护由 xsrfCookieNamexsrfHeaderName 两个配置项共同完成:Axios 会从 xsrfCookieName 指定的 cookie 中读取 token,再写入 xsrfHeaderName 指定的请求头里发给后端。两者默认值分别是 XSRF-TOKENX-XSRF-TOKEN,如果后端约定了不同的字段名,需要在创建实例时显式覆盖。要注意边界:cookie 只能被同源页面读取,跨域请求通常碰不到那个 token,所以 XSRF 这套只对同源请求有意义,不能拿来当作跨域安全机制。


五、创建 Axios 实例

为什么需要实例

创建实例可以设置默认配置,适用于需要多个不同配置的 API 场景:

const apiClient = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json'
  }
});

// 使用实例发送请求
const response = await apiClient.get('/users');

实例方法

实例拥有与 axios 相同的方法别名:

const instance = axios.create({
  baseURL: 'https://api.example.com'
});

// 等价于 axios.get()
instance.get('/users');

// 等价于 axios.post()
instance.post('/users', { name: 'John' });

// 获取完整 URL
const uri = instance.getUri({ url: '/users', params: { ID: 123 } });
// -> https://api.example.com/users?ID=123

六、拦截器

请求拦截器

请求拦截器用于在请求发送前修改配置或添加通用逻辑:

axios.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    console.log('请求发送:', config.url);
    return config;
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

响应拦截器

响应拦截器用于在处理响应前统一处理:

axios.interceptors.response.use(
  function (response) {
    // 对响应数据做点什么
    console.log('响应成功:', response.status);
    return response;
  },
  function (error) {
    // 对响应错误做点什么
    console.error('响应错误:', error.message);
    return Promise.reject(error);
  }
);

移除与清空拦截器

use() 的返回值是这条拦截器的编号,把它传给 eject() 就能移除;clear() 则一次清空同类拦截器:

const logger = axios.interceptors.request.use(config => {
  console.log('发送:', config.url);
  return config; // 不返回 config,后续拿到的请求头会是 undefined
});

axios.interceptors.request.eject(logger);
const apiClient = axios.create();

// 清空该实例上所有请求/响应拦截器
apiClient.interceptors.request.clear();
apiClient.interceptors.response.clear();

ejectclear 对全局 axiosaxios.create 的实例都有效。开发热更新场景下,先用 clear() 清场再注册,比让旧拦截器反复叠加要可靠。

多个拦截器的执行顺序

两类拦截器的方向相反,这是官方文档明确约定的行为:请求拦截器后添加先执行(LIFO)响应拦截器先添加先执行(FIFO)

axios.interceptors.request.use(fn1);
axios.interceptors.request.use(fn3);
// 执行顺序:fn3 -> fn1 -> 请求发出(后添加的先执行)

axios.interceptors.response.use(fn4);
axios.interceptors.response.use(fn5);
// 执行顺序:fn4 -> fn5 -> 业务代码(先添加的先执行)

LIFO 有个容易踩的实际影响:请求拦截器有依赖关系时(先取 token、再把 token 写进 header),被依赖的那个要最后注册——它会最先执行。注册顺序写反,写 header 的那一步拿到的就是空 token。

一次请求的完整流转

把本节的机制串起来,一次 apiClient.get('/users') 从发到收会经过这些站:

  1. 合并配置:请求级 config 优先于实例 defaults,实例 defaults 优先于全局 defaults;
  2. 请求拦截器按注册的逆序依次通过,后添加的先碰 config;
  3. 适配器发出请求:默认按 xhr → http → fetch 的顺序选环境支持的第一个,浏览器走 XMLHttpRequest,Node.js 走 http,Cloudflare Workers、Deno 这类环境走 fetch;需要时可用 adapter 配置显式指定;
  4. 响应返回,validateStatus 判定这个状态码算不算成功;
  5. 响应拦截器按注册顺序依次通过,先添加的先碰 response;
  6. then 里的业务代码拿到 response 对象。

任何一环抛出的错误都会跳进同一条 rejection 链,最后在 catch 里以 AxiosError 的形式被接住——这正是下一节错误处理的地基。


七、错误处理

错误类型

async function fetchData() {
  try {
    const response = await axios.get('/user/12345');
    console.log(response.data);
  } catch (error) {
    if (axios.isCancel(error)) {
      console.log('请求被取消');
    } else if (error.code === 'ECONNABORTED') {
      console.log('请求超时');
    } else if (error.response) {
      // 服务器返回错误状态码
      console.log('服务器错误:', error.response.status);
      console.log('错误数据:', error.response.data);
    } else {
      // 请求配置错误或网络问题
      console.log('请求错误:', error.message);
    }
  }
}

获取错误信息

try {
  await axios.get('/user/12345');
} catch (error) {
  if (error.response) {
    console.log('状态码:', error.response.status);
    console.log('响应数据:', error.response.data);
    console.log('请求配置:', error.config);
  } else {
    console.log('错误信息:', error.message);
  }
}

AxiosError 的结构

Axios v1 抛出的错误是 AxiosError 实例,用 error.responseerror.requesterror.configerror.code 四个字段就能区分出错误发生在哪一层:

字段含义典型场景
error.response服务端返回了响应(4xx/5xx)服务器正常响应但状态码非 2xx
error.request已发出请求但没收到响应网络中断、DNS 失败、服务端无响应
error.config触发错误的请求配置排查时回溯请求参数
error.code错误代号字符串超时是 ECONNABORTED,取消是 ERR_CANCELED

判断顺序应固定为:先看 error.response,再看 error.request,最后才用 error.message。因为 error.responseerror.request 一旦存在就说明请求确实发出了,剩下的 message 才是配置或其它问题。若需要完整错误快照用于上报,可直接调用 error.toJSON()


八、请求取消

AbortController(推荐方式)

浏览器与 Node.js 15+ 都原生支持:

const controller = new AbortController();

async function fetchData() {
  try {
    const response = await axios.get('/user/12345', {
      signal: controller.signal
    });
    console.log(response);
  } catch (error) {
    if (axios.isCancel(error)) {
      console.log('请求被取消');
    } else {
      console.error(error);
    }
  }
}

// 取消请求
controller.abort();

取消多个请求

const controller = new AbortController();

Promise.all([
  axios.get('/user/1', { signal: controller.signal }),
  axios.get('/user/2', { signal: controller.signal }),
  axios.get('/user/3', { signal: controller.signal })
]).then(function (results) {
  console.log(results);
});

// 批量取消
controller.abort();

v0.x 的 CancelToken 与 v1.x 的差异

如果你在旧代码里见过 CancelToken,它基于已被撤回的 Promise 提案设计,自 v0.22.0 起官方就标记为废弃,并推荐改用标准化的 AbortController。二者并不等价:CancelToken 在 v1 中仍可用,但官方不建议在新项目里使用,新代码应统一用 signalisCancel(error) 对两种取消方式产生的错误都返回 true,所以上文错误处理里的取消分支无需改动。

升级时不必依赖错误对象的 code 字符串去区分取消来源——以 axios.isCancel(error) 为准即可,code 在不同版本或不同取消方式下并不稳定。


九、数据序列化

URLSearchParams

const params = new URLSearchParams();
params.append('username', 'john');
params.append('password', 'secret');

await axios.post('/login', params);

自动序列化

Axios v1.x 支持自动将对象序列化为 URL 编码格式:

await axios.post('/user', {
  username: 'john',
  password: 'secret',
  // 自动序列化为 username=john&password=secret
}, {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
});

FormData 上传

const formData = new FormData();
formData.append('file', fileObject);
formData.append('name', 'my-file');

await axios.post('/upload', formData, {
  headers: {
    'Content-Type': 'multipart/form-data'
  }
});

自动 FormData 序列化

Axios 支持直接将对象转换为 FormData:

await axios.post('/upload', {
  name: 'my-file',
  file: fileObject
}, {
  headers: {
    'Content-Type': 'multipart/form-data'
  }
});

十、配置默认值

全局默认值

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.timeout = 5000;
axios.defaults.headers.common['Authorization'] = 'Bearer token';

实例默认值

const api = axios.create({
  baseURL: 'https://api.example.com'
});

api.defaults.timeout = 10000;

配置优先级

配置项优先级从高到低:

  1. 请求的 config
  2. 实例的 defaults
  3. 全局的 defaults
// 全局设置 timeout 为 5000
axios.defaults.timeout = 5000;

// 实例设置 timeout 为 1000
const api = axios.create();
api.defaults.timeout = 1000;

// 此次请求设置 timeout 为 2000(优先)
api.get('/user', { timeout: 2000 });
// 此次请求使用 2000

十一、速率限制

请求间隔控制

class RateLimiter {
  constructor(maxRequests, intervalMs) {
    this.requests = [];
    this.maxRequests = maxRequests;
    this.intervalMs = intervalMs;
  }

  async execute(fn) {
    // 窗口满了就等到最早的请求滑出窗口,再重新检查,而不是只等一次
    for (;;) {
      const now = Date.now();
      this.requests = this.requests.filter(t => now - t < this.intervalMs);

      if (this.requests.length < this.maxRequests) {
        this.requests.push(now);
        return fn();
      }

      const oldest = this.requests[0];
      await new Promise(r => setTimeout(r, this.intervalMs - (now - oldest) + 1));
    }
  }
}

const limiter = new RateLimiter(5, 1000); // 1 秒最多 5 个请求

for (const id of userIds) {
  await limiter.execute(() => axios.get(`/user/${id}`));
}

这套实现只管单个进程内的请求。服务一旦横向扩成多个实例,各进程的计数器互不知情,真正的限流要挪到网关或 Redis 这类共享存储上做。


十二、实践建议

统一错误处理

// 创建封装函数
async function apiRequest(method, url, data = null, config = {}) {
  try {
    const response = await axios({
      method,
      url,
      data,
      ...config
    });
    return { success: true, data: response.data };
  } catch (error) {
    if (error.response) {
      return {
        success: false,
        status: error.response.status,
        message: error.response.data?.message || '服务器错误'
      };
    } else if (error.request) {
      return {
        success: false,
        message: '网络连接失败'
      };
    } else {
      return {
        success: false,
        message: error.message
      };
    }
  }
}

// 使用
const result = await apiRequest('get', '/users');
if (result.success) {
  console.log(result.data);
} else {
  console.error(result.message);
}

请求重试机制

axios.interceptors.response.use(
  response => response,
  async error => {
    const config = error.config;

    // 被取消的请求不算失败;配置阶段就出错的请求没有 config,都无法也不该重试
    if (axios.isCancel(error) || !config) {
      return Promise.reject(error);
    }

    // 只重试网络错误(无响应)和 5xx,最多 3 次
    if (!config._retry) {
      config._retry = 0;
    }

    const shouldRetry = (!error.response || error.response.status >= 500) && config._retry < 3;
    if (shouldRetry) {
      config._retry++;
      await new Promise(r => setTimeout(r, 1000 * config._retry));
      return axios(config);
    }

    return Promise.reject(error);
  }
);

两个边界要守住:axios.isCancel(error) 挡在重试之前,否则调用方明明主动取消的动作还会被偷偷重发;重放用的 axios(config) 是全局实例,如果请求走的是 axios.create 创建的客户端,重放要改成同一个实例的调用,否则实例上的默认值和拦截器会被绕开。

请求日志

axios.interceptors.request.use(config => {
  console.group(`🚀 ${config.method?.toUpperCase()} ${config.url}`);
  console.log('参数:', config.params);
  console.log('数据:', config.data);
  console.log('时间:', new Date().toISOString());
  console.groupEnd();
  return config;
});

axios.interceptors.response.use(
  response => {
    console.group(`✅ ${response.status} ${response.config.url}`);
    console.log('响应:', response.data);
    console.groupEnd();
    return response;
  },
  error => {
    console.group(`❌ ${error.config?.url}`);
    console.error('错误:', error.message);
    console.groupEnd();
    return Promise.reject(error);
  }
);

十三、常见问题

Q:Axios 和 fetch 哪个更好?

取决于使用场景

  • 选择 Axios:需要简洁的 API、良好的错误处理、内置拦截器、请求取消、JSON 自动处理
  • 选择 fetch:项目不想引入额外依赖、现代浏览器环境、需要更底层的控制

Q:如何处理 CORS 跨域?

Axios 本身不处理 CORS,CORS 需要后端配置。如果遇到 CORS 问题:

  1. 确认后端设置了正确的 Access-Control-Allow-Origin
  2. 使用代理服务器转发请求
  3. 需要携带跨域 cookies 时,客户端配置 withCredentials: true,服务端同时返回 Access-Control-Allow-Credentials: true,两端缺一不可

Q:如何处理文件下载?

// 浏览器端文件下载
async function downloadFile(url, filename) {
  const response = await axios.get(url, {
    responseType: 'blob',
    onDownloadProgress: (progressEvent) => {
      if (!progressEvent.total) return; // 没有 Content-Length 时 total 为 0,百分比无意义
      const percentCompleted = Math.round(
        (progressEvent.loaded * 100) / progressEvent.total
      );
      console.log(`下载进度: ${percentCompleted}%`);
    }
  });

  const link = document.createElement('a');
  link.href = URL.createObjectURL(new Blob([response.data]));
  link.download = filename;
  link.click();
  URL.revokeObjectURL(link.href);
}

下载时要把 responseType 设为 blob,进度通过 onDownloadProgress 监听;当响应没有 Content-Length(比如走 chunked 传输)时 total 为 0,此时只能拿到已传输字节数,算不出百分比。

Q:如何处理大文件上传?

const formData = new FormData();
formData.append('file', largeFile);

// 使用 onUploadProgress 监控进度
await axios.post('/upload', formData, {
  headers: { 'Content-Type': 'multipart/form-data' },
  onUploadProgress: (progressEvent) => {
    if (!progressEvent.total) return;
    const percentCompleted = Math.round(
      (progressEvent.loaded * 100) / progressEvent.total
    );
    console.log(`上传进度: ${percentCompleted}%`);
  }
});

Q:如何设置代理?

Node.js 环境下,Axios v1.x 通过 proxy 配置项直接指定代理,不需要手写 agent:

await axios.get('/user', {
  proxy: {
    protocol: 'http',
    host: 'proxy-server',
    port: 8080,
    auth: {
      username: 'user',
      password: 'pass'
    }
  }
});

代理地址也可以放进 HTTP_PROXY / HTTPS_PROXY 环境变量,Axios 在 Node.js 环境会自动读取并应用。


十四、自测与采用顺序

自测清单

对照下面的问题检查自己理解到了哪一层,答不出的回到对应章节再看一遍:

  1. 为什么 axios.get() 成功时得到的不是数据本身,而是 response?如何让调用方直接拿到数据?
  2. axios.create() 的实例、全局 axios.defaults 和单次请求的 config 三者,优先级谁最高?
  3. 往同一个实例注册三个请求拦截器,执行顺序是什么?换成响应拦截器呢?一个拦截器要依赖另一个的产出时,注册顺序该怎么排?
  4. 响应拦截器里如何区分"拿到了 4xx 响应"和"根本没收到响应"?依据是哪两个字段?
  5. AbortController 取消请求后,错误对象有哪些特征?axios.isCancel() 为什么比看 error.code 可靠?
  6. 上传和下载进度分别由哪两个回调监听?什么情况下拿不到百分比?

采用顺序建议

把 Axios 引入一个新项目时,建议按下面的顺序推进,避免一上来就堆拦截器和重试逻辑:

  1. 先跑通基础请求:直接用 axios.get / axios.post 发一两个请求,确认 baseURL、超时、JSON 自动解析符合预期。这一步只验证"能不能用"。
  2. 创建实例收敛配置:把 baseURL、timeout、公共 headers 收敛到一个 axios.create 实例里,业务代码只引用实例,不再用全局 axios
  3. 加请求拦截器:在请求拦截器里统一注入 Authorization、traceId 等公共头,避免每个调用点重复写。
  4. 加响应拦截器做错误归一:把 4xx/5xx/网络错误/超时归一成统一结构,业务层只判断 result.success,不再各自 try/catch。
  5. 按需加取消和重试:在容易出现"快速连点"或"长轮询"的场景引入 AbortController;在调用第三方不稳定接口时引入有限重试。不要全局开重试,否则会放大下游压力。
  6. 加监控和日志:在拦截器里打请求耗时、状态码、错误类型,接入团队的监控上报通道。

这个顺序背后的逻辑是:先把"能用"跑通,再做"统一",最后才做"加固"。跳过中间步骤直接加重试和监控,往往会让代码在还没收敛时就堆满分支。

生态现状

Axios 是浏览器侧使用最广的 HTTP 客户端。根据 npm trends 的公开数据,它的周下载量长期处在本类别的第一梯队;GitHub 上 109.2k Stars、11.8k Forks(axios/axios,2026-09-08)。

它被广泛用于以下场景:

  • 前端框架(React、Vue、Angular)的 SPA 项目
  • 移动端开发(React Native、Ionic)
  • Node.js 服务端调用第三方 API
  • Electron 桌面应用

在 Node.js 18+ 环境下,原生 fetch 已经稳定,部分纯服务端项目开始用 fetchkygot 替代 Axios;但在浏览器侧,Axios 的拦截器、超时、取消三件套仍然是最省心的选择。

相关资源

资源链接
官方文档https://axios.rest(axios-http.com/docs 已重定向至此)
GitHubhttps://github.com/axios/axios
npmhttps://www.npmjs.com/package/axios
npm trendshttps://npmtrends.com/axios

参与讨论

使用 GitHub 登录。欢迎补充事实、异议与实践。