Axios 知识点全面总结

文章目录

Axios 知识点全面总结

一、Axios 基础概念

1. 什么是 Axios?

Axios 是一个 基于 Promise 的 HTTP 客户端库,用于浏览器和 Node.js 环境中发送 HTTP 请求。它支持 请求 / 响应拦截、请求取消、Promise 链式调用 等特性,是前端开发中最常用的 HTTP 库之一。

2. 核心特性

  • 支持浏览器和 Node.js 环境
  • 基于 Promise 实现,支持 async/await
  • 提供请求 / 响应拦截器,方便处理请求和响应数据
  • 支持请求取消(通过 CancelToken 或 AbortController)
  • 自动转换请求和响应数据(JSON 数据处理)
  • 支持请求超时设置、自定义请求头、并发请求等

二、安装与基本用法

1. 安装

bash 复制代码
# 通过 npm 安装
npm install axios

# 通过 yarn 安装
yarn add axios

# 浏览器直接引入(CDN)
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

2. 基本请求示例

javascript 复制代码
// 发送 GET 请求
axios.get('/api/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('请求错误:', error);
  });

// 发送 POST 请求
axios.post('/api/user', {
  name: '张三',
  age: 25
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  console.error('请求错误:', error);
});

// 使用 async/await
async function fetchData() {
  try {
    const response = await axios.get('/api/data');
    return response.data;
  } catch (error) {
    throw new Error('获取数据失败: ' + error.message);
  }
}

三、请求方法与参数

方法 描述 参数格式
axios.get(url, config) 发送 GET 请求(获取资源) url, config(可选配置)
axios.post(url, data, config) 发送 POST 请求(提交资源) url, data(请求体), config
axios.put(url, data, config) 发送 PUT 请求(更新资源) url, data, config
axios.delete(url, config) 发送 DELETE 请求(删除资源) url, config
axios.head(url, config) 发送 HEAD 请求(获取资源头部信息) url, config
axios.patch(url, data, config) 发送 PATCH 请求(部分更新资源) url, data, config

示例:带参数的 GET 请求

javascript 复制代码
// 方式一:通过 params 参数传递查询参数
axios.get('/api/users', {
  params: {
    id: 1,
    name: '张三'
  }
})

// 方式二:直接拼接 URL(不推荐,手动处理编码)
axios.get('/api/users?id=1&name=张三')

四、请求配置选项(config)

Axios 的请求配置可用于自定义请求行为,常用配置如下:

  • 基础配置
javascript 复制代码
{
  url: '/api/data',             // 请求 URL
  method: 'get',                // 请求方法(get/post/put等)
  baseURL: 'https://api.example.com', // 基础 URL,会与 url 拼接
  timeout: 5000,                // 请求超时时间(毫秒),超过则报错
  withCredentials: true,        // 是否携带 cookie(跨域请求时)
  responseType: 'json',         // 响应数据类型(json/blob/text等)
  headers: { 'X-Custom-Header': 'value' }, // 请求头
}
  • 请求数据相关
javascript 复制代码
{
  data: { key: value },         // POST/PUT 等请求的请求体数据
  params: { id: 1 },            // GET 请求的查询参数
  paramsSerializer: function(params) {
    // 自定义参数序列化方式
    return Qs.stringify(params, { arrayFormat: 'brackets' });
  }
}

五、拦截器(Interceptors)

拦截器用于在请求发送前或响应接收后统一处理数据,分为 请求拦截器响应拦截器

  1. 请求拦截器
javascript 复制代码
// 添加请求拦截器
axios.interceptors.request.use(
  config => {
    // 在请求发送前做些什么(如添加 token、修改请求头)
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    // 处理请求错误
    return Promise.reject(error);
  }
);
  1. 响应拦截器
javascript 复制代码
// 添加响应拦截器
axios.interceptors.response.use(
  response => {
    // 对响应数据做统一处理(如错误码判断、数据格式化)
    const { data } = response;
    if (data.code !== 200) {
      // 错误处理(如提示用户、跳转登录页)
      throw new Error(data.message || '请求失败');
    }
    return data; // 直接返回处理后的数据,简化后续 then 操作
  },
  error => {
    // 处理响应错误(如网络错误、404、500 等)
    const { response } = error;
    if (response) {
      // 响应已接收但状态码非 2xx
      switch (response.status) {
        case 401:
          console.log('未授权,请重新登录');
          break;
        case 404:
          console.log('资源不存在');
          break;
        default:
          console.log('服务器错误');
      }
    } else {
      // 网络错误(如超时、断网)
      console.log('网络连接失败');
    }
    return Promise.reject(error);
  }
);
  1. 移除拦截器
javascript 复制代码
const myInterceptor = axios.interceptors.request.use(...);
axios.interceptors.request.eject(myInterceptor); // 移除请求拦截器

六、错误处理

Axios 的错误处理通过 catch 或 try/catch 实现,常见错误类型:

javascript 复制代码
axios.get('/api/data')
  .then(response => {
    // 处理成功响应
  })
  .catch(error => {
    if (axios.isAxiosError(error)) {
      // 处理 Axios 错误(如请求错误、响应错误)
      console.log('Axios 错误:', error.message);
      console.log('错误状态码:', error.response?.status);
      console.log('错误响应数据:', error.response?.data);
    } else {
      // 处理其他错误(如网络错误)
      console.log('其他错误:', error);
    }
  });

七、取消请求

在组件卸载或请求不再需要时,可取消请求以避免资源浪费。

  1. 使用 CancelToken(旧方式)
javascript 复制代码
import axios from 'axios';

const source = axios.CancelToken.source();

axios.get('/api/data', {
  cancelToken: source.token
}).then(response => {
  // 处理响应
}).catch(error => {
  if (axios.isCancel(error)) {
    console.log('请求已取消:', error.message);
  }
});

// 取消请求
source.cancel('用户取消了请求');
  1. 使用 AbortController(推荐,浏览器原生支持)
javascript 复制代码
const controller = new AbortController();
const signal = controller.signal;

axios.get('/api/data', { signal })
  .then(response => {
    // 处理响应
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('请求已取消');
    }
  });

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

八、并发请求

Axios 提供 axios.all 方法处理多个并发请求,并通过 axios.spread 分配结果。

javascript 复制代码
const request1 = axios.get('/api/data1');
const request2 = axios.get('/api/data2');

axios.all([request1, request2])
  .then(axios.spread((response1, response2) => {
    // 两个请求都成功时执行
    console.log('数据1:', response1.data);
    console.log('数据2:', response2.data);
  }))
  .catch(errors => {
    // 任一请求失败时执行
    console.log('并发请求错误:', errors);
  });

九、创建实例(Instance)

当需要不同配置的请求时,可创建多个 Axios 实例。

javascript 复制代码
// 创建自定义实例
const instance = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json'
  }
});

// 使用实例发送请求
instance.get('/users')
  .then(response => {
    console.log(response.data);
  });

// 为实例添加拦截器
instance.interceptors.request.use(...);

十、与框架集成

  1. 在 Vue 中使用
javascript 复制代码
// main.js 中配置
import axios from 'axios';
Vue.prototype.$axios = axios; // 将 axios 挂载到 Vue 实例上

// 组件中使用
this.$axios.get('/api/data')
  .then(response => {
    this.data = response.data;
  });
  1. 在 React 中使用
javascript 复制代码
import axios from 'axios';

function fetchData() {
  return axios.get('/api/data')
    .then(response => response.data);
}

function MyComponent() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetchData().then(setData);
    // 组件卸载时取消请求(使用 AbortController)
    const controller = new AbortController();
    return () => controller.abort();
  }, []);
  
  // ...
}

十一、最佳实践与常见问题

  1. 设置默认配置
javascript 复制代码
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
  1. 处理跨域请求

    前端设置 withCredentials: true

    后端配置 CORS 响应头(如 Access-Control-Allow-Origin)

  2. 请求超时重试

javascript 复制代码
// 封装超时重试函数
function retryRequest(config, retries = 3) {
  return new Promise((resolve, reject) => {
    const attempt = () => {
      axios(config)
        .then(resolve)
        .catch(error => {
          if (error.code === 'ECONNABORTED' && retries > 0) {
            // 超时错误且还有重试次数
            setTimeout(() => {
              retryRequest(config, retries - 1).then(resolve, reject);
            }, 1000);
          } else {
            reject(error);
          }
        });
    };
    attempt();
  });
}
  1. 与 Fetch API 对比
    Axios 优势:浏览器 / Node 通用、拦截器、自动转换 JSON、错误处理更友好
    Fetch 优势:浏览器原生支持、更简洁的 API、支持 AbortController(需 polyfill 兼容旧浏览器)

十二、TypeScript 支持

Axios 原生支持 TypeScript,可通过泛型指定响应数据类型:

typescript 复制代码
interface User {
  id: number;
  name: string;
}

// 指定响应数据类型为 User 数组
axios.get<User[]>('/api/users')
  .then(response => {
    // response.data 会被推断为 User[] 类型
    const firstUser = response.data[0].name;
  });

十三、Axios 调用后端全局 API

1、全局方法 httpClient.js

javascript 复制代码
import axios from 'axios';

// 创建 axios 实例
const service = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API, // 从环境变量获取API基础URL
  timeout: 5000, // 请求超时时间
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
});

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么
    // 例如添加 token
    const token = localStorage.getItem('token');
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    // 对请求错误做些什么
    console.log(error); // for debug
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  response => {
    // 对响应数据做点什么
    const res = response.data;
    // 假设业务状态码 200 表示成功
    if (res.code !== 200) {
      console.log(res.message || 'Error');
      return Promise.reject(new Error(res.message || 'Error'));
    } else {
      return res;
    }
  },
  error => {
    // 对响应错误做点什么
    console.log('err' + error); // for debug
    return Promise.reject(error);
  }
);

export default service;  

2、四种 HTTP 方法 封装 api.js

javascript 复制代码
import service from './httpClient';

/**
 * get 请求
 * @param {string} url 请求路径
 * @param {object} params 请求参数
 * @returns {Promise}
 */
export function get(url, params) {
  return service({
    url,
    method: 'get',
    params
  });
}

/**
 * post 请求
 * @param {string} url 请求路径
 * @param {object} data 请求数据
 * @returns {Promise}
 */
export function post(url, data) {
  return service({
    url,
    method: 'post',
    data
  });
}

/**
 * put 请求
 * @param {string} url 请求路径
 * @param {object} data 请求数据
 * @returns {Promise}
 */
export function put(url, data) {
  return service({
    url,
    method: 'put',
    data
  });
}

/**
 * delete 请求
 * @param {string} url 请求路径
 * @param {object} params 请求参数
 * @returns {Promise}
 */
export function del(url, params) {
  return service({
    url,
    method: 'delete',
    params
  });
}  

3、使用封装方法 userService.js

javascript 复制代码
import { get, post, put, del } from './api';

// 获取用户列表
export function getUserList(params) {
  return get('/api/users', params);
}

// 创建用户
export function createUser(data) {
  return post('/api/users', data);
}

// 更新用户信息
export function updateUser(id, data) {
  return put(`/api/users/${id}`, data);
}

// 删除用户
export function deleteUser(id) {
  return del(`/api/users/${id}`);
}  

这个封装包含三个主要部分:

  1. 基础配置和拦截器设置(httpClient.js)
  2. 四种 HTTP 方法的封装(api.js)
  3. 示例服务模块(userService.js)展示如何使用封装的方法
相关推荐
iCOD3R15 分钟前
Skill - kill-ai-slop 解决“AI 味”样式
前端·css·ai编程
shuaijie051824 分钟前
强制修改调用接口的api地址。
javascript·vue.js·ecmascript
JerrySir31 分钟前
恶意 npm 包只活了 17 分钟:技术面试里,为什么“升级依赖”还不算止血?
javascript·安全
皮音31 分钟前
Skill 在项目中的实践 —— 从 Agent 困境到 Skill 工程化
前端
白帽小阳40 分钟前
2026前端面试题!(附答案及解析)
javascript·网络·python·安全·web安全·网络安全·护网行动
大龄秃头程序员44 分钟前
RN 0.86 新架构实战:TurboModule + Fabric 组件 + iOS 原生容器,完整代码开源
前端·react native
这是个栗子1 小时前
前端开发中的常用工具函数(八)
开发语言·前端·javascript
Hilaku1 小时前
Vue 和 React 真正的差距,不在语法,而在团队犯错成本
前端·javascript·程序员
研☆香1 小时前
为什么变量声明在赋值前也能使用?—— 深入理解 JavaScript 变量提升与作用域
开发语言·前端·javascript
Liora_Yvonne1 小时前
目录结构到底怎么设计?别再把 components 和 utils 当垃圾桶了
前端