Axios全解析:从基础到高级实战技巧

目录

  1. 核心特性

  2. 安装配置

  3. 基础使用

  4. 高级功能

  5. 错误处理

  6. 拦截器机制

  7. 请求取消

  8. TypeScript支持

  9. 最佳实践

  10. 常见问题


1. 核心特性

1.1 核心优势
  • 全平台支持:浏览器 & Node.js 双环境

  • 自动转换:JSON数据自动序列化

  • 拦截器系统:请求/响应全链路控制

  • 取消令牌:精准控制请求生命周期

  • 防御性设计:XSRF 跨站攻击防护

  • 进度跟踪:文件上传下载进度监控

1.2 性能对比
特性AxiosFetch API
浏览器兼容性IE11+Chrome 42+
请求取消需AbortController
超时设置原生支持需手动封装
拦截器内置系统需自行实现
上传进度事件监听不可用

2. 安装配置

2.1 安装方式

# NPM
npm install axios

# Yarn
yarn add axios

# CDN (浏览器环境)
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
 
2.2 全局配置

// 设置基准路径
axios.defaults.baseURL = 'https://api.yourdomain.com/v2';

// 配置超时时间(毫秒)
axios.defaults.timeout = 10000; 

// 设置公共头信息
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
 

3. 基础使用

3.1 发起请求

// GET请求(参数自动编码)
axios.get('/user', {
  params: {
    ID: 12345,
    role: 'admin'
  }
})

// POST请求(自动序列化JSON)
axios.post('/user', {
  firstName: 'Fred',
  lastName: 'Flintstone'
})

// 并发请求
const [userRes, orderRes] = await Promise.all([
  axios.get('/user/123'),
  axios.get('/orders?user=123')
]);
 
3.2 响应结构解析

{
  data: {},       // 响应主体
  status: 200,    // HTTP状态码
  statusText: 'OK',
  headers: {},    // 响应头(自动格式化)
  config: {},     // 请求配置
  request: {}     // 原始请求对象
}
 

4. 高级功能

4.1 创建实例

const apiClient = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000,
  headers: {'X-Custom-Header': 'foobar'}
});

// 使用实例
apiClient.get('/products');
 
4.2 文件上传(含进度)

const formData = new FormData();
formData.append('file', fileInput.files[0]);

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

5. 错误处理

5.1 错误类型识别

axios.get('/user/123')
  .catch(error => {
    if (error.response) {
      // 服务端响应异常(2xx外的状态码)
      console.log('服务器错误:', error.response.status);
    } else if (error.request) {
      // 请求已发送但无响应
      console.log('网络错误:', error.message);
    } else {
      // 配置错误
      console.log('配置错误:', error.message);
    }
  });
 
5.2 全局错误处理

// 响应拦截器统一处理
axios.interceptors.response.use(
  response => response,
  error => {
    const status = error.response?.status;
    if (status === 401) {
      window.location.href = '/login';
    } else if (status >= 500) {
      alert('服务器异常,请稍后重试');
    }
    return Promise.reject(error);
  }
);
 

6. 拦截器机制

6.1 请求拦截器

axios.interceptors.request.use(config => {
  // 添加认证令牌
  const token = localStorage.getItem('authToken');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  
  // 添加时间戳防止缓存
  config.params = {
    ...config.params,
    _t: Date.now()
  };
  
  return config;
});
 
6.2 响应拦截器

axios.interceptors.response.use(
  response => {
    // 统一处理业务状态码
    if (response.data.code !== 200) {
      return Promise.reject(response.data.msg);
    }
    return response.data;
  },
  error => {
    // 统一错误格式
    return Promise.reject({
      code: error.response?.status || 0,
      message: error.message
    });
  }
);
 

7. 请求取消

7.1 CancelToken方案(旧版)

const source = axios.CancelToken.source();

axios.get('/user', {
  cancelToken: source.token
});

// 取消请求
source.cancel('用户主动取消操作');
7.2 Fetch AbortController(推荐)

const controller = new AbortController();

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

// 取消请求
controller.abort('页面跳转取消');
 

8. TypeScript支持

8.1 响应类型定义

interface UserProfile {
  id: number;
  name: string;
  email: string;
}

axios.get<UserProfile>('/user/123')
  .then(response => {
    console.log(response.data.name); // 自动类型推断
  });
 
8.2 扩展默认配置

declare module 'axios' {
  interface AxiosRequestConfig {
    retry?: number; // 自定义重试配置
    showLoading?: boolean;
  }
}

// 使用自定义配置
axios.get('/data', { 
  retry: 3,
  showLoading: true 
});
 

9. 最佳实践

9.1 分层架构

src/
├─ api/
│  ├─ auth.ts       // 认证相关接口
│  ├─ product.ts    // 商品模块接口
│  └─ index.ts      // 统一导出
├─ utils/
│  └─ request.ts    // Axios实例封装
 
9.2 安全实践

// CSRF防御
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFToken';

// 速率限制
const rateLimitedAxios = axios.create();
let lastRequestTime = 0;

rateLimitedAxios.interceptors.request.use(config => {
  const now = Date.now();
  if (now - lastRequestTime < 1000) {
    return Promise.reject(new Error('请求过于频繁'));
  }
  lastRequestTime = now;
  return config;
});
 

10. 常见问题

Q1: 如何防止重复提交?

const pendingRequests = new Map();

axios.interceptors.request.use(config => {
  const requestKey = `${config.method}-${config.url}`;
  if (pendingRequests.has(requestKey)) {
    return Promise.reject(new Error('重复请求已阻止'));
  }
  pendingRequests.set(requestKey, true);
  
  config.complete = () => {
    pendingRequests.delete(requestKey);
  };
  return config;
});
 
Q2: 大文件分片上传?

async function uploadLargeFile(file) {
  const CHUNK_SIZE = 5 * 1024 * 1024; // 5MB
  const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
  
  for (let i = 0; i < totalChunks; i++) {
    const chunk = file.slice(i * CHUNK_SIZE, (i+1) * CHUNK_SIZE);
    await axios.post('/upload-chunk', {
      chunk,
      index: i,
      total: totalChunks,
      fileHash: file.hash
    });
  }
}
 

进阶资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值