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('网络请求超时,请稍后重试');
     }
    }
   })
  }
}
相关推荐
牧码岛1 小时前
Web前端之JavaScrip中的Array、Object、Map和Set详解
前端·javascript·web·web前端
Bigger1 小时前
😮‍💨 有了 AI 之后,我怎么感觉反而更累了?
前端·aigc·ai编程
Dxy12393102161 小时前
HTML中使用Canvas动态图形渲染:解锁Web交互新维度
前端·html·图形渲染
西陵1 小时前
如何实现 Claude 生成式 UI?一套可落地的工程方案
前端·人工智能·ai编程
FlyWIHTSKY1 小时前
Vue 3 + 原生 CSS Float
前端·css·vue.js
energy_DT1 小时前
2026海上钻井平台可视化运维:红外热成像、超声波、AI视频巡检、数字孪生
前端
ONLYOFFICE1 小时前
如何将 Word 集成到 Web 应用程序? 5 种方法详解与对比
前端·word·onlyoffice
533_1 小时前
[pinia] vue3中监听pinia值的变化
前端·javascript·vue.js
一叶飘零晋1 小时前
【(二)Electron 使用之常用技巧】
javascript·electron·ecmascript