axios二次封装 (TypeScript)

168 阅读2分钟

安装依赖包

npm i axios

拦截器方法

src/services/index.ts

import axios from "axios";
import type { AxiosInstance, AxiosRequestConfig, InternalAxiosRequestConfig } from "axios";
import { RootObject } from '../model/rootObject'

// 导出Request类,可以用来自定义传递配置来创建实例
export class Request {
      // axios 实例
      instance: AxiosInstance;
      // 基础配置,url和超时时间
      baseConfig: AxiosRequestConfig = { baseURL: "http://localhost:5000", timeout: 60000 };

      constructor(config: AxiosRequestConfig) {
            // 使用axios.create创建axios实例
            this.instance = axios.create(Object.assign(this.baseConfig, config));

            this.instance.interceptors.request.use(
                  (config: InternalAxiosRequestConfig) => {
                        // 一般会请求拦截里面加token,用于后端的验证
                        const authorization = localStorage.getItem('token')
                        if (authorization) {
                              config.headers!.authorization = authorization;
                        }

                        return config;
                  },
                  (err: any) => {
                        // 请求错误,这里可以用全局提示框进行提示
                        return Promise.reject(err);
                  }
            );

            this.instance.interceptors.response.use(
                  (res: any) => {
                        // 直接返回res,当然你也可以只返回res.data
                        // 系统如果有自定义code也可以在这里处理
                        return res.data;
                  },
                  (err: any) => {
                        // 这里用来处理http常见错误,进行全局提示
                        let message = "";
                        switch (err.status) {
                              case 400:
                                    message = "请求错误(400)";
                                    break;
                              case 401:
                                    message = "未授权,请重新登录(401)";
                                    // 这里可以做清空storage并跳转到登录页的操作
                                    break;
                              case 403:
                                    message = "拒绝访问(403)";
                                    break;
                              case 404:
                                    message = "请求出错(404)";
                                    break;
                              case 408:
                                    message = "请求超时(408)";
                                    break;
                              case 500:
                                    message = "服务器错误(500)";
                                    break;
                              case 501:
                                    message = "服务未实现(501)";
                                    break;
                              case 502:
                                    message = "网络错误(502)";
                                    break;
                              case 503:
                                    message = "服务不可用(503)";
                                    break;
                              case 504:
                                    message = "网络超时(504)";
                                    break;
                              case 505:
                                    message = "HTTP版本不受支持(505)";
                                    break;
                              default:
                                    message = `连接出错(${err.status})!`;
                        }
                        return Promise.reject(err.response);
                  }
            );
      }

      // 定义请求方法
      public request(config: AxiosRequestConfig): Promise<RootObject<any>> {
            return this.instance.request(config);
      }

      public get<T = any>(
            url: string,
            config?: AxiosRequestConfig
      ): Promise<RootObject<T>> {
            return this.instance.get(url, config);
      }

      public post<T = any>(
            url: string,
            data?: any,
            config?: AxiosRequestConfig
      ): Promise<RootObject<T>> {
            return this.instance.post(url, data, config);
      }

      public put<T = any>(
            url: string,
            data?: any,
            config?: AxiosRequestConfig
      ): Promise<RootObject<T>> {
            return this.instance.put(url, data, config);
      }

      public patch<T = any>(
            url: string,
            data?: any,
            config?: AxiosRequestConfig
      ): Promise<RootObject<T>> {
            return this.instance.patch(url, data, config);
      }

      public delete<T = any>(
            url: string,
            config?: AxiosRequestConfig
      ): Promise<RootObject<T>> {
            return this.instance.delete(url, config);
      }
}

// 默认导出Request实例
export default new Request({})

封装响应数据

export type RootObject<T> = {
    code: number
    msg: string
    data: T
}

统一管理接口

src/services/loginRequest.ts

import requests from ".";

export const createPlan_API = (data: any) => request.post<PlanData>(`${basic_path}`, data)
export const getPlanAll_API = () => request.get<PlanData[]>(`${basic_path}`)
export const deletePlan_API = (idList: number[]) => request.delete(`${basic_path}/${idList}`)
export const updatePlan_API = (id: number, data: any) => request.patch(`${basic_path}/${id}`, data)

配置代理解决跨域问题

vue.config.js

devServer: {
    https: true, // 默认是false, 默认就是http协议,true将http协议转换为https协议
    // 代理配置
    proxy: {
      '/api': { // 配置需要代理的路径 --> 这里的意思是代理http://localhost:80/api/后的所有路由
        target: 'https://172.20.9.153:8085', // 目标地址 --> 服务器地址
        changeOrigin: true, // 允许跨域
        ws: true,  // 允许websocket代理
        // 如果这里没有进行路径重写,当你访问http://localhost:80/api/login/,实际上访问的就是https://172.20.9.153:8085/api/login/
        pathRewrite: { // 重写代理路径
          // 就是把路径中的api都替换为空的字符串
          '^/api': '', // 因为服务端地址里面是没有api字段的,api只是为了区别需要代理的路径,如果服务端有api字段则不需要重新	
        }
      }
    }
  }