ts简易网络请求封装

发布时间 2023-04-26 21:45:24作者: zjxgdq
  1. utils/axios/type/axios.ts
    export type ErrorMessageMode = "none" | "modal" | "message" | undefined;
    export interface RequestOptions {
      // Splicing request parameters to url
      joinParamsToUrl?: boolean;
      // Format request parameter time
      formatDate?: boolean;
      // Whether to process the request result
      isTransformResponse?: boolean;
      // Whether to return native response headers
      // For example: use this attribute when you need to get the response headers
      isReturnNativeResponse?: boolean;
      // Whether to join url
      joinPrefix?: boolean;
      // Interface address, use the default apiUrl if you leave it blank
      apiUrl?: string;
      // 请求拼接路径
      urlPrefix?: string;
      // Error message prompt type
      errorMessageMode?: ErrorMessageMode;
      // Whether to add a timestamp
      joinTime?: boolean;
      ignoreCancelToken?: boolean;
      // Whether to send token in header
      withToken?: boolean;
    }
    export interface Result<T = unknown> {
      code: number;
      type: "success" | "error" | "warning";
      message: string;
      result: T;
    }
    // multipart/form-data: upload file
    export interface UploadFileParams {
      // Other parameters
      data?: any;
      // File parameter interface field name
      name?: string;
      // file name
      file: File | Blob;
      // file name
      filename?: string;
      [key: string]: any;
    }
    

      

  2. utils/axios/config.ts
    import type { AxiosRequestConfig } from "axios";
    import type { RequestOptions } from "./types/axios";
    export interface CreateAxiosOptions extends AxiosRequestConfig {
      requestOptions?: RequestOptions;
    }
    export function DefaultAxiosConfig(): CreateAxiosOptions {
      return {
        baseURL: "/api",
        headers: {
          "Content-Type": "application/json;charset=UTF-8",
          "Access-Control-Allow-Origin-Type": "*",
        },
        timeout: 30000,
        withCredentials: true,
        validateStatus() {
          return true;
        },
        requestOptions: {
          isTransformResponse: true,
        },
      };
    }
    

     

  3. utils/axios/index.ts

    import { FrogAxios } from "./frog-axios";
    import { DefaultAxiosConfig } from "./config";
    function createFrogAxios() {
      return new FrogAxios(DefaultAxiosConfig());
    }
    export const defHttp = createFrogAxios();
    

      

  4. utils/axios/frog-axios.ts

    import axios, { type InternalAxiosRequestConfig } from "axios";
    import type {
      AxiosInstance,
      AxiosRequestConfig,
      AxiosResponse,
      AxiosError,
    } from "axios";
    import type { CreateAxiosOptions } from "./config";
    import type { RequestOptions, Result } from "./types/axios";
    import { errorHandle } from "./errorHandle";
    export class FrogAxios {
      private axiosInstance: AxiosInstance;
      private readonly options: CreateAxiosOptions;
      constructor(options: CreateAxiosOptions) {
        this.options = options;
        this.axiosInstance = axios.create(options);
        this.setupInterceptors();
      }
      private setupInterceptors() {
        /**
         * 请求拦截器
         * 每次请求前,如果存在token则在请求头中携带token
         */
        this.axiosInstance.interceptors.request.use(
          (config:InternalAxiosRequestConfig<any>) => {
            config.data = JSON.stringify(config.data);
            return config;
          },
          (error) => {
            return Promise.reject(error);
          }
        );
        this.axiosInstance.interceptors.response.use(
          (response:AxiosResponse<any, any>) => {
            if (response.status === 200) {
              return response;
            } else {
              errorHandle(response.status);
              console.log(response);
              return response;
            }
          },
          (error) => {
            if (!navigator.onLine) {
              console.log("网络不可用,请链接网络");
              // message.error('网络不可用,请链接网络');
            }
          }
        );
      }
      post<T = unknown>(
        config: AxiosRequestConfig,
        options?: RequestOptions
      ): Promise<T> {
        return this.request({ ...config, method: "POST" }, options);
      }
      get<T = unknown>(
        config: AxiosRequestConfig,
        options?: RequestOptions
      ): Promise<T> {
        return this.request({ ...config, method: "GET" }, options);
      }
      request<T = unknown>(
        config: AxiosRequestConfig,
        options?: RequestOptions
      ): Promise<T> {
        const conf: CreateAxiosOptions = config;
        const { requestOptions } = this.options;
        const opt: RequestOptions = Object.assign({}, requestOptions, options);
        conf.requestOptions = opt;
        return new Promise((resolve, reject) => {
          this.axiosInstance
            .request<unknown, AxiosResponse<Result>>(conf)
            .then((res: AxiosResponse<Result>) => {
              resolve(res as unknown as Promise<T>);
            })
            .catch((e: Error | AxiosError) => {
              reject(e);
            });
        });
      }
    }
    

     

  5. utils/axios/errorHandle.ts 

    // import { message } from 'antd';
    export const errorHandle = (status: number) => {
      // 状态码判断
      switch (status) {
        case 400:
          console.log(status);
          // message.warning('发出的请求有错误,服务器没有进行新建或修改数据的操作==>' + status);
          break;
        case 401: // 重定向
          console.log(status);
          // message.warning('token:登录失效==>' + status);
          break;
        case 404:
          console.log(status);
          // message.warning('网络请求不存在==>' + status);
          break;
        case 410:
          console.log(status);
          // message.warning('请求的资源被永久删除,且不会再得到的==>' + status);
          break;
        case 500:
          console.log("500");
          // message.error('服务器发生错误,请检查服务器==>' + status);
          break;
        case 502:
          console.log(status);
          // message.error('网关错误==>' + status);
          break;
        case 503:
          console.log(status);
          // message.error('服务不可用,服务器暂时过载或维护==>' + status);
          break;
        case 504:
          console.log(status);
          // message.error('网关超时==>' + status);
          break;
        default:
          console.log(status);
        // message.error('其他错误错误==>' + status);
      }
    };
    

     

  6. services/index.ts

    import { defHttp } from "@/utils/axios";
    import type { RootObject } from "./type";
    export async function handleList() {
      return await defHttp.get<RootObject>({ url: "/v2/index_entry" });
    }
    

      

  7. services/type.ts

    /*
     * @Description: 
     * @Date: 2023-04-25 22:54:12
     * @Author: grab
     * @Copyright: (c) 2018-2022 宁波哥爱帮科技有限公司
     */
    export interface RootObject {
        data: Datum[];
        status: number;
        statusText: string;
        headers: Headers;
        config: Config;
        request: Env;
      }
      
      interface Config {
        transitional: Transitional;
        adapter: string[];
        transformRequest: null[];
        transformResponse: null[];
        timeout: number;
        xsrfCookieName: string;
        xsrfHeaderName: string;
        maxContentLength: number;
        maxBodyLength: number;
        env: Env;
        headers: Headers2;
        baseURL: string;
        withCredentials: boolean;
        method: string;
        url: string;
      }
      
      interface Headers2 {
        Accept: string;
        'Access-Control-Allow-Origin-Type': string;
      }
      
      interface Env {
      }
      
      interface Transitional {
        silentJSONParsing: boolean;
        forcedJSONParsing: boolean;
        clarifyTimeoutError: boolean;
      }
      
      interface Headers {
        'access-control-allow-credentials': string;
        'access-control-allow-headers': string;
        'access-control-allow-methods': string;
        'access-control-allow-origin': string;
        'content-encoding': string;
        'content-type': string;
        date: string;
        etag: string;
        server: string;
        vary: string;
        'x-powered-by': string;
      }
      
      interface Datum {
        id: number;
        is_in_serving: boolean;
        description: string;
        title: string;
        link: string;
        image_url: string;
        icon_url: string;
        title_color: string;
        __v: number;
      }
    

      

  8. 使用

    <template>
      <view class="content">
        <view @click="get()">网络请求点击事件测试</view>
      </view>
    </template>
      
    <script lang="ts">
    import type { RootObject } from "@/services/type";
    import { defineComponent } from "vue";
    import { handleList} from "../../services/index";
    export default defineComponent({
      setup() {
        function get() {
          handleList().then((res:RootObject) => {
            console.log(res.data);
          });
        }
        return {
          get,
        };
      },
    });
    </script>
    
      
      <style>
    </style>
    
    function get() {
      throw new Error('Function not implemented.');
    }