Xi-Yuer

Xi-Yuer

github

Axios請求

基於 Axios 封裝一個通用請求#

Type.d.ts#

// type
import type {
    AxiosRequestConfig,
    InternalAxiosRequestConfig,
    AxiosInterceptorOptions,
    AxiosResponse,
} from 'axios'

// 擴展攔截器
export interface RequestConfig extends AxiosRequestConfig {
    requestInterceptor?: {
        onFulfilled?: (
            value: InternalAxiosRequestConfig,
        ) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>
        onRejected?: ((error: any) => any) | null
        options?: AxiosInterceptorOptions
    }

    responseInterceptor?: {
        onFulfilled?: (value: AxiosResponse) => AxiosResponse
        onRejected?: ((error: any) => any) | null
        options?: AxiosInterceptorOptions
    }
}

export type InterceptorType = Partial<
    Pick<RequestConfig, 'requestInterceptor' | 'responseInterceptor'>
>

export interface IResponse<T = any> {
    data: T
    message: string
    statusCode: number
    timestamp: Date
}

請求類#

// request
import axios, {
    type AxiosInstance,
    type AxiosResponse,
    type CancelTokenSource,
} from 'axios'
import type { IResponse, InterceptorType, RequestConfig } from './type'

class Request {
    Instance: AxiosInstance | null
    constructor(
        // 實例的請求基礎路徑
        private readonly baseURL: string,
        // 實例的請求超時時間
        private readonly timeOUT: number,
        // 實例的攔截器
        private readonly interceptor?: InterceptorType,
        // 取消令牌
        private cancelTokenSource: CancelTokenSource | null = null,
    ) {
        // 創建一個實例
        this.Instance = axios.create({
            baseURL: this.baseURL,
            timeout: this.timeOUT,
        })
        // 配置實例的請求攔截
        if (this.interceptor?.requestInterceptor) {
            this.Instance.interceptors.request.use(
                this.interceptor.requestInterceptor.onFulfilled,
                this.interceptor.requestInterceptor.onRejected,
                this.interceptor.requestInterceptor.options,
            )
        }
        // 配置實例的響應攔截
        if (this.interceptor?.responseInterceptor) {
            this.Instance.interceptors.response.use(
                this.interceptor.responseInterceptor.onFulfilled,
                this.interceptor.responseInterceptor.onRejected,
                this.interceptor.responseInterceptor.options,
            )
        }
    }
    // 實例方法 request
    public request<T = AxiosResponse<any>>(config: RequestConfig): Promise<T> {
        return new Promise<T>((resolve, reject) => {
            // 單個接口的請求攔截
            if (config.requestInterceptor) {
                this.Instance?.interceptors.request.use(
                    config.requestInterceptor.onFulfilled,
                    config.requestInterceptor.onRejected,
                    config.requestInterceptor.options,
                )
            }
            // 單個接口的響應攔截
            if (config.responseInterceptor) {
                this.Instance?.interceptors.response.use(
                    config.responseInterceptor.onFulfilled,
                    config.responseInterceptor.onRejected,
                    config.responseInterceptor.options,
                )
            }

            this.cancelTokenSource = axios.CancelToken.source()
            this.Instance?.request<T>({
                ...config,
                cancelToken: this.cancelTokenSource.token,
            })
                .then((res) => {
                    resolve(res as any)
                })
                .catch((err) => {
                    reject(err)
                })
        })
    }

    // 取消請求
    public cancelRequest(): void {
        if (this.cancelTokenSource) {
            this.cancelTokenSource.cancel('取消請求')
        }
    }

    public get<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'GET', ...config })
    }
    public post<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'POST', ...config })
    }
    public delete<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'DELETE', ...config })
    }
    public patch<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'PATCH', ...config })
    }
    public put<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'PUT', ...config })
    }
    public head<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'HEAD', ...config })
    }
    public options<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'OPTIONS', ...config })
    }
    public trace<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'TRACE', ...config })
    }
    public connect<T = any>(config: RequestConfig) {
        return this.request<T>({ method: 'CONNECT', ...config })
    }
}

使用方式#

/**
 *
 * ================================================================================
 * ===================================測試代碼=====================================
 * ================================================================================
 *
 */
const instance = new Request('https://xiyuer.club/api/v1', 10000, {
    requestInterceptor: {
        onFulfilled(config) {
            console.log('實例請求成功攔截')
            return config
        },
        onRejected(error) {
            console.log('實例請求失敗攔截')
            return error
        },
    },
    responseInterceptor: {
        onFulfilled(value) {
            console.log('實例響應成功攔截')
            return value.data
        },
        onRejected(error) {
            console.log('實例響應失敗攔截')
            return error
        },
    },
})

type IData = any[]

const getBanner = () => {
    instance
        .get<IResponse<IData>>({
            url: '/banner',
            requestInterceptor: {
                onFulfilled(config) {
                    console.log('接口請求成功攔截')
                    return config
                },
                onRejected(err) {
                    console.log('接口請求失敗攔截')
                    return err
                },
            },
            responseInterceptor: {
                onFulfilled(data) {
                    console.log('接口響應成功攔截')
                    return data
                },
                onRejected(err) {
                    console.log('接口響應失敗攔截')
                    return err
                },
            },
        })
        .then((res) => {
            console.log(res)
        })
}
getBanner()
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。