JavaScript - 相对实用的Axios二次封装

1. 为什么要对Axios进行二次封装?

如果不对Axios进行二次封装,可以想象到每次调用Axios都需要对其重复的进行配置。

并且封装Axios,也能够使得每次请求的入口相同,更加便于管理。

2. 如何对Axios进行二次封装

首先我们需要构建出一个axios实例用于发送请求,以及需要绑定一些方法,使得每次请求的入口都是这些方法。其次,错误处理和令牌数据携带需要在Axios拦截器进行构造。

构建HTTP请求类:

kotlin 复制代码
import axios from "axios";
import baseConfig from "./baseConfig";
import { InterceptorController } from "./InterceptorController";
class HTTP {
  constructor(extraConfig) {
   const mergeConfig = {...baseConfig,...extraConfig};
   this.ins = axios.create({
    ...mergeConfig
   })
   
   /** 创建拦截器实例 */
   const interceptorController = new InterceptorController(this.ins)
   interceptorController.addRequestInterceptor.apply(this);
   interceptorController.addResponseInterceptor.apply(this);
  }
  
  /** 通用的请求方法 */
  async request(url, config) {
   try {
    return await this.ins({ url, ...config, });
   } catch (error) {
    throw error.response ? error.response.data : error;
   }
  }
  
  post(url, data, config){
   return this.request(url, { ...config, data, method: 'POST' });
  }
  
  get(url, config) {
   return this.request(url, { ...config, method: 'GET' });
  }
}

构建Axios拦截器:

javascript 复制代码
import qs from 'qs';
import { responseCodeMap } from 'responseCodeMap.js';
/** axios拦截控制器 */
export class InterceptorController {
  /**
   * @param ins - axios实例
   */
  constructor(ins) {
   this.ins = ins;
   /** 用于超时重试计数 */
   this.retryCount = 1;
  };
  
  addRequestInterceptor() {
   this.ins.interceptors.request.use((config) => {
    loading();
    
    /** 携带token,假设token存入了store中 */
    const token = store.commit('token');
    if(store.commit('getToken')){
     config.headers.token = token;
    }else{
     redirectTo('login');
    }
    
    config.data = qs.stringify(config.data);
   },(error) => {
    closeLoading();
    
    /** 重定向到错误页面 */
    redirectTo('error' + error.response.status);
    
    return Promise.reject(error);
   });
  }
  
  addResponseInterceptor(){
   this.ins.interceptors.response.use((res) => {
    closeLoading();
    return res;
   },(error) => {
    closeLoading();
    /** 超时重发请求 */
    if(error.code === 'ECONNABORTED' && error.message.includes('timeout')){
     const config = error.config;
     
     if(this.retryCount <= 3){
      this.retryCount++;
      console.warn(`请求超时,第${this.retryCount - 1}次重试`);
      return new Promise(resolve => {
       setTimeout(() => {
        resolve(this.ins(config));
       }, 1000);
      });
     }else{
      console.error('请求重试失败,已达最大重试次数');
      this.retryCount = 1;
      $message.error('网络请求超时,请稍后重试');
     }
    }
   })
  }
}
相关推荐
山河木马9 分钟前
矩阵专题2-怎么创建视图矩阵(uViewMatrix)
javascript·webgl·计算机图形学
小林攻城狮12 分钟前
使用 Transport 节流解决 Vercel AI SDK 流式渲染卡死问题
前端·react.js
前端缘梦17 分钟前
告别 TS 运行时类型漏洞!Zod 完整入门实战教程(前端 / 全栈必备)
前端·react.js·全栈
the_answer37 分钟前
Webpack vs Vite 深度对比分析
前端·webpack
转转技术团队1 小时前
验证码识别实战:前端不写页面,改训模型了?
前端
MomentYY1 小时前
Temperature:AI 的“脑洞旋钮”
前端·llm·ai编程
远航_1 小时前
OpenSpec 完整详细介绍
前端·后端
召钱熏1 小时前
状态枚举正确≠渲染正确:一个语音按钮的状态机边界修复实录
android·前端
SkyWalking中文站1 小时前
认识 Horizon UI · 1/17:SkyWalking 新一代可观测性控制台
运维·前端·监控
cidy_981 小时前
Dify 操作教程:工作流编排 & Chat 对话编排
前端·工作流引擎