ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Axios实例化与拦截器在TypeScript中的实战应用

Axios实例化与拦截器在TypeScript中的实战应用 1. Axios实例化与拦截器实战指南在前端开发中网络请求是不可避免的核心环节。作为Vue/React等现代框架的黄金搭档Axios凭借其简洁的API和强大的拦截器机制成为处理HTTP请求的首选方案。今天我们就来深入探讨如何在TypeScript环境中创建具备完整拦截器功能的Axios实例。提示本文示例基于axios 1.3.4版本和TypeScript 4.9环境所有代码可直接用于实际项目1.1 为什么需要自定义Axios实例直接使用axios全局对象虽然方便但在企业级项目中会遇到几个典型问题不同模块需要不同的baseURL配置某些接口需要特殊headers处理错误处理逻辑需要统一管理请求响应需要统一数据转换通过创建独立的axios实例我们可以为不同业务模块定制专属的请求配置。比如用户模块的请求可能需要携带token而公开API则不需要认证头。2. 基础实例创建与配置2.1 初始化Axios实例在src/api目录下创建index.ts文件这是管理所有API请求的入口文件。我们先从最基本的实例创建开始import axios from axios // 创建基础实例 const service axios.create({ baseURL: import.meta.env.VITE_API_BASEURL, // 从环境变量读取基础地址 timeout: 15000, // 超时时间 headers: { Content-Type: application/json;charsetutf-8 } })这里有几个关键配置项需要注意baseURL应该通过环境变量配置便于不同环境切换timeout建议设置在10-30秒之间根据业务需求调整Content-Type默认使用application/json如需form-data需单独配置2.2 环境变量配置技巧在Vite项目中环境变量需要以VITE_前缀开头才能在客户端使用。建议在.env文件中配置# .env.development VITE_API_BASEURL /api # .env.production VITE_API_BASEURL https://api.yourdomain.com3. 拦截器深度解析3.1 请求拦截器实现请求拦截器的主要应用场景包括添加认证token请求参数预处理请求日志记录// 请求拦截器 service.interceptors.request.use( (config) { // 在发送请求前处理config const token localStorage.getItem(access_token) if (token) { config.headers.Authorization Bearer ${token} } return config }, (error) { // 对请求错误处理 return Promise.reject(error) } )实际开发中常见的请求拦截场景接口加密对敏感参数进行加密处理性能监控记录请求开始时间参数校验验证必填参数是否存在3.2 响应拦截器实现响应拦截器的主要职责统一错误处理数据格式标准化响应日志记录// 响应拦截器 service.interceptors.response.use( (response) { // 2xx范围内的状态码触发 const res response.data // 假设后端统一返回结构为{code, data, message} if (res.code ! 200) { // 处理业务逻辑错误 ElMessage.error(res.message || Error) return Promise.reject(new Error(res.message || Error)) } return res.data // 只返回实际需要的数据部分 }, (error) { // 超出2xx范围的状态码触发 if (error.response) { // 根据HTTP状态码处理不同错误 switch (error.response.status) { case 401: // 跳转到登录页 break case 403: // 显示权限不足 break case 500: // 服务器错误 break default: console.error(请求错误 ${error.response.status}) } } return Promise.reject(error) } )4. 高级配置技巧4.1 多实例管理对于大型项目建议按业务模块创建多个实例// 用户相关API实例 const userService axios.create({ baseURL: ${import.meta.env.VITE_API_BASEURL}/user, timeout: 10000 }) // 商品相关API实例 const productService axios.create({ baseURL: ${import.meta.env.VITE_API_BASEURL}/product, timeout: 8000 })4.2 TypeScript类型增强为API响应添加类型定义可以极大提升开发体验interface ApiResponseT any { code: number data: T message: string } // 在拦截器中应用类型 service.interceptors.response.use( (response: AxiosResponseApiResponse) { // ... } )4.3 取消请求实现对于长时间未响应的请求可以使用CancelToken取消const controller new AbortController() // 在请求配置中添加signal service.get(/api, { signal: controller.signal }) // 需要时取消请求 controller.abort()5. 实战问题排查指南5.1 常见问题速查表问题现象可能原因解决方案拦截器未生效使用了axios而非实例确保所有请求都通过自定义实例发起TypeScript类型错误响应类型未正确定义为ApiResponse添加泛型支持请求被重复发送未正确处理拦截器Promise链确保拦截器中返回处理后的configCORS问题服务端未配置跨域检查服务端Access-Control-Allow-Origin5.2 性能优化建议合理设置timeout根据接口平均响应时间设置避免在拦截器中执行重逻辑会影响所有请求性能使用缓存对静态数据请求添加缓存策略压缩请求数据对大体积请求体启用压缩6. 完整示例代码以下是整合了所有功能的完整实现// src/api/index.ts import axios, { type AxiosRequestConfig, type AxiosResponse } from axios import { ElMessage } from element-plus // 定义基础响应类型 interface ApiResponseT any { code: number data: T message: string } // 创建axios实例 const service axios.create({ baseURL: import.meta.env.VITE_API_BASEURL, timeout: 15000, headers: { Content-Type: application/json;charsetutf-8 } }) // 请求拦截器 service.interceptors.request.use( (config: AxiosRequestConfig) { // 添加认证token const token localStorage.getItem(access_token) if (token) { config.headers { ...config.headers, Authorization: Bearer ${token} } } return config }, (error) { return Promise.reject(error) } ) // 响应拦截器 service.interceptors.response.use( (response: AxiosResponseApiResponse) { const res response.data if (res.code ! 200) { ElMessage.error(res.message || Error) return Promise.reject(new Error(res.message || Error)) } return res.data }, (error) { if (error.response) { switch (error.response.status) { case 401: router.push(/login) break case 403: ElMessage.error(无权限访问) break default: ElMessage.error(error.response.data?.message || 服务异常) } } return Promise.reject(error) } ) export default service在实际项目中我通常会根据业务需求对拦截器进行扩展。比如添加请求重试机制、接口节流控制等。一个经验之谈是拦截器中的逻辑应该保持简洁复杂的业务处理应该放在具体的API调用处。对于需要特殊处理的API可以直接在请求配置中覆盖拦截器的默认行为// 跳过响应拦截器的处理 service.get(/special-api, { transformResponse: [(data) data] })最后要提醒的是拦截器中的错误处理应该与项目的全局错误处理机制协调一致避免重复处理或遗漏处理。在我的实践中会建立一个统一的错误处理中心来管理所有异常情况。
返回列表