Axios 介绍

97 阅读3分钟

1. 作用

Axios 是一个基于 Promise 的现代化 HTTP 客户端库,专为浏览器和 Node.js 设计。它的核心作用包括:

  • 发送 HTTP 请求:支持 GET、POST、PUT、DELETE 等所有常见方法。
  • 处理异步操作:通过 Promise 或 async/await 管理异步请求。
  • 拦截请求和响应:在请求发送前或响应返回后插入处理逻辑。
  • 自动转换数据:自动将请求/响应数据转换为 JSON(或其他格式)。
  • 防御 XSRF:内置跨站请求伪造(XSRF)防护机制。
  • 取消请求:支持中止正在进行的请求。

2. 解决的问题

在 Axios 出现前,开发者面临以下痛点:

  • 原生 fetch API 功能简陋:缺乏超时控制、进度监控、拦截器等。
  • XMLHttpRequest 复杂繁琐:需手动处理状态码、错误、数据转换。
  • 回调地狱:传统回调方式导致代码嵌套深、可读性差。
  • 兼容性问题:需额外适配不同浏览器环境。
  • 重复代码:每个请求都需写错误处理、Header 配置等逻辑。

Axios 通过 简洁的 API + 强大功能 一站式解决上述问题。


3. 基础使用

安装

npm install axios
# 或
yarn add axios

示例代码

import axios from 'axios';

// GET 请求
axios.get('https://api.example.com/data')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

// POST 请求
axios.post('https://api.example.com/users', {
  name: 'Alice',
  age: 28
})
  .then(res => console.log(res.data));

// 并发请求
const [userRes, orderRes] = await axios.all([
  axios.get('/user'),
  axios.get('/orders')
]);

4. 高级功能

(1) 全局配置

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

(2) 拦截器(Interceptors)

// 请求拦截器
axios.interceptors.request.use(config => {
  config.headers['X-Request-ID'] = uuidv4(); // 添加唯一ID
  return config;
});

// 响应拦截器
axios.interceptors.response.use(
  response => response.data, // 直接返回核心数据
  error => {
    if (error.response?.status === 401) {
      redirectToLogin(); // 统一处理未授权
    }
    return Promise.reject(error);
  }
);

(3) 取消请求

const controller = new AbortController();

axios.get('/data', { signal: controller.signal })
  .catch(err => {
    if (axios.isCancel(err)) {
      console.log('请求被取消');
    }
  });

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

5. 常见封装方案

封装目标:

  • 统一错误处理
  • 管理基础 URL 和 Token
  • 简化 API 调用
  • 支持 TypeScript 类型

完整封装示例:

// src/utils/axios.js
import axios from 'axios';

// 创建实例
const instance = axios.create({
  baseURL: import.meta.env.VITE_API_URL, // 从环境变量读取
  timeout: 10000,
});

// 请求拦截器
instance.interceptors.request.use(config => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// 响应拦截器
instance.interceptors.response.use(
  response => response.data, // 直接返回核心数据
  error => {
    // 统一错误处理
    const message = error.response?.data?.message || error.message;
    showNotification(`请求失败: ${message}`); // 显示错误提示
    return Promise.reject(error);
  }
);

// 封装通用方法
const http = {
  get: (url, params) => instance.get(url, { params }),
  post: (url, data) => instance.post(url, data),
  put: (url, data) => instance.put(url, data),
  delete: url => instance.delete(url),
};

export default http;

业务层调用:

// src/api/user.js
import http from '@/utils/axios';

export const userApi = {
  login: (email, password) => 
    http.post('/auth/login', { email, password }),
  
  getProfile: () => 
    http.get('/user/profile'),
  
  updateAvatar: avatarFile => {
    const formData = new FormData();
    formData.append('avatar', avatarFile);
    return http.post('/user/avatar', formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    });
  }
};

TypeScript 增强版:

// 添加泛型支持
interface ResponseData<T> {
  code: number;
  data: T;
  message: string;
}

const http = {
  get: <T>(url: string, params?: object): Promise<T> => 
    instance.get<ResponseData<T>>(url, { params }).then(res => res.data),
  
  post: <T>(url: string, data?: object): Promise<T> => 
    instance.post<ResponseData<T>>(url, data).then(res => res.data),
};

6. 对比原生 fetch

功能AxiosFetch API
语法简洁度✅ 链式调用❌ 需手动处理响应
JSON 转换✅ 自动转换❌ 需手动调用 .json()
取消请求✅ AbortController✅ AbortController
超时控制✅ 内置支持❌ 需用 setTimeout 封装
拦截器✅ 完善支持❌ 需手动实现
浏览器兼容性✅ 支持 IE11+❌ 不兼容 IE

最佳实践建议

  1. 环境隔离:通过 .env 文件管理不同环境的 baseURL
  2. 错误分级:区分网络错误、业务错误、认证错误
  3. 安全加固
    • 使用 CSRF Token
    • 敏感请求添加二次确认
  4. 性能优化
    • 请求防抖(如搜索框)
    • 合理设置缓存策略
  5. 类型安全:用 TypeScript 定义接口响应结构