Skip to content
☆´∀`☆
On this page

axios 的又又又封装,这次用了 ts

复习一下 ts 嘿嘿。

基础 server

  • 入参
    • axiosConfig
    • 自定义业务配置(业务相关的请求拦截,业务相关的响应拦截,.......)
  • 返回
    • axios 实例

处理请求和响应拦截。响应拦截中会处理通用的 http 错误。响应拦截一旦被拦截就会进入 reject 状态。

js
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";

const NETWORK_STATUS_MAP: { [index: number]: string } = {
  400: "错误的请求",
  401: "未授权,请重新登录",
  403: "拒绝访问",
  404: "请求错误,未找到该资源",
  405: "请求方法未允许",
  408: "请求超时",
  500: "服务器端出错",
  501: "网络未实现",
  502: "网络错误",
  503: "服务不可用",
  504: "网络超时",
  505: "http版本不支持该请求",
};
/**
 * 自定义的响应拦截返回类型
 */
export interface IBusinessInterceptorsResponse {
  flag: boolean;
  msg: string;
}
/**
 * 自定义请求拦截fn
 */
type interceptorsRequestType = (config: AxiosRequestConfig) => AxiosRequestConfig;
/**
 * 自定义响应拦截fn
 */
type interceptorsResponseType = (response: AxiosResponse) => IBusinessInterceptorsResponse;
/**
 * 业务类配置
 */
export interface IBusinessConfig {
  interceptorsRequest?: interceptorsRequestType;
  interceptorsResponse?: interceptorsResponseType;
}
/**
 * @description: useuseuse
 * @param {AxiosRequestConfig} config
 * @param {IBusinessConfig} businessConfig
 * @return {*}
 */
const useServer = (config: AxiosRequestConfig, businessConfig?: IBusinessConfig) => {
  const server: AxiosInstance = axios.create(config);
  /**
   * 请求拦截
   */
  server.interceptors.request.use((config: AxiosRequestConfig) => {
    // 全局请求拦截
    // 自定义请求拦截 业务头,权限啥的塞这哟
    if (businessConfig?.interceptorsRequest) {
      config = businessConfig.interceptorsRequest(config);
    }

    return config;
  });
  /**
   * 响应拦截 如果被拦截了 就reject啦
   */
  server.interceptors.response.use(
    (response: AxiosResponse) => {
      // 全局响应拦截器
      const { status } = response;
      let message = "";
      // http异常
      if (status < 200 && status >= 300) {
        message = NETWORK_STATUS_MAP?.[status] || `其他连接错误 -- ${status}`;
        // ```````这里应该有个msg弹出提示
        return Promise.reject(message);
      }
      if (businessConfig?.interceptorsResponse) {
        const { flag, msg } = businessConfig.interceptorsResponse(response);
        if (!flag) {
          // ````````这里应该有个msg弹出提示
          return Promise.reject(msg);
        }
      }
      return Promise.resolve(response.data);
    },
    err => {
      // `````````这里应该有个msg弹出提示
      return Promise.reject(err);
    }
  );
  return server;
};
export default useServer;

拓展 API

封装 post,get 等基础请求,当需要进行传不同数据类型的请求可能会用到它。

  • 入参
    • axios 实例
  • 返回
    • post,get.....
js
import { AxiosInstance } from "axios";

const useApi = (server: AxiosInstance) => {
  /**
   * @description: 平平无奇get
   * @param {string} url
   * @param {object} params
   * @return {Promise}
   */
  function get(url: string, params: { [index: string]: any } = {}) {
    return server.get(url, {
      params,
    });
  }
  /**
   * @description: 平平无奇post
   * @param {string} url
   * @param {object} data
   * @return {Promise}
   */
  function post(url: string, data: { [index: string]: any } = {}) {
    return server.post(url, {
      data,
    });
  }
  /**
   * @description: post formdata数据 传对象啊 自动转formdata啦 我也不知道为什么功能相似的接口有的要用json有的要用formdata
   * @param {string} url
   * @param {object} data
   * @return {*}
   */
  function postFormData(url: string, data: { [index: string]: any } = {}) {
    const formData = new FormData();
    for (const key in data) {
      formData.append(key, data[key]);
    }
    return server.post(url, {
      data,
      headers: { "Content-Type": "multipart/form-data" },
    });
  }
  // ········其他什么传参格式不同啦,接受格式不同啦的全塞这
  return {
    post,
    get,
    postFormData,
  };
};

export default useApi;

基础使用

js
import useServer from "@/libs/axios";
import useApi from "@/libs/axios/useApi";

const server = useServer({
  baseURL: "",
  timeout: 6000,
});
const { post, get } = useApi(server);

export { post, get };

取消请求的拓展

  • 当有重复 url 请求时,取消上一个请求~简单整一个,按需细化~
  • 可以用在 useServer 的拦截里,也可以用在 useApi 的具体请求中~
js
import axios from "axios";

export default () => {
  const cancelRequestMap: Map<string, () => void> = new Map();

  function getCancelToken(url: string) {
    if (cancelRequestMap.has(url)) {
      // 重复了 取消上一个请求
      const cancelFn = cancelRequestMap.get(url);
      cancelFn && cancelFn();
      cancelRequestMap.delete(url);
      // 再插入新的请求
      return pushCancel(url);
    }
    return pushCancel(url);
  }
  function pushCancel(url: string) {
    const cancelToken = new axios.CancelToken(c => {
      cancelRequestMap.set(url, c);
    });
    return cancelToken;
  }
  function delCancel(url: string) {
    cancelRequestMap.delete(url);
  }
  return {
    getCancelToken,
    delCancel,
  };
};