TS-封裝axios

記錄一下使用ts封裝axios,供參考:

type Method = 'GET' | 'POST' | 'PUT' | 'DELETE'
type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'

interface AxiosRequest {
    baseURL?: string;
    url: string;
    data?: any;
    params?: any;
    method?: Method;
    headers?: any;
    timeout?: number;
    responseType?: ResponseType;
}

interface CustomResponse {
    readonly status: boolean;
    readonly message: string;
    data: any;
    origin?: any;
}


import axios, { AxiosRequestConfig } from 'axios';

// 定義接口
interface PendingType {
    url?: string;
    method?: Method;
    params: any;
    data: any;
    cancel: Function;
}

// 取消重復請求
const pending: Array<PendingType> = [];
const CancelToken = axios.CancelToken;

// axios 實例
const instance = axios.create({
    timeout: 10000,
    responseType: 'json'
});

// 移除重復請求
const removePending = (config: AxiosRequestConfig) => {
    for (const key in pending) {
        const item: number = +key;
        const list: PendingType = pending[key];
        // 當前請求在數(shù)組中存在時執(zhí)行函數(shù)體
        if (list.url === config.url && list.method === config.method && JSON.stringify(list.params) === JSON.stringify(config.params) && JSON.stringify(list.data) === JSON.stringify(config.data)) {
            // 執(zhí)行取消操作
            list.cancel('操作太頻繁,請稍后再試');
            // 從數(shù)組中移除記錄
            pending.splice(item, 1);
        }
    }
};

// 添加請求攔截器
instance.interceptors.request.use(
    (request:any) => {
        // TODO: handle loading

        removePending(request);
        request.cancelToken = new CancelToken((c) => {
            pending.push({ url: request.url, method: request.method, params: request.params, data: request.data, cancel: c });
        });
        return request;
    },
    (error: any) => {
        return Promise.reject(error);
    }
);
// 添加響應攔截器
instance.interceptors.response.use(
    (response: any) => {
        removePending(response.config);

        const errorCode = response?.data?.errorCode;
        switch (errorCode) {
            case '401':
                // 根據(jù)errorCode,對業(yè)務做異常處理(和后端約定)
                break;
            default:
                break;
        }

        return response;
    },
    (error: any) => {
        const response = error.response;

        // 根據(jù)返回的http狀態(tài)碼做不同的處理
        switch (response?.status) {
            case 401:
                // token失效
                break;
            case 403:
                // 沒有權限
                break;
            case 500:
                // 服務端錯誤
                break;
            case 503:
                // 服務端錯誤
                break;
            default:
                break;
        }

        return Promise.reject(response || {message: error.message});
    }
);

class BaseHttp {
    // 外部傳入的baseUrl
    protected baseURL: string = process.env. NODE_ENV as string;
    // 自定義header頭
    protected headers: object = {
        ContentType: 'application/json;charset=UTF-8'
    }

    private apiAxios({ 
        baseURL = this.baseURL, 
        headers = this.headers, 
        method, 
        url, 
        data, 
        params, 
        responseType 
    }: AxiosRequest): Promise<CustomResponse> {

        return new Promise((resolve, reject) => {
            instance({
                baseURL,
                headers,
                method,
                url,
                params,
                data,
                responseType
            }).then((res: any) => {
                // 200:服務端業(yè)務處理正常結束
                if (res.status === 200) {
                    // TODO ...
                    // resolve({});
                } else {
                    resolve({ 
                        status: false, 
                        message: res.data?.errorMessage || (url + '請求失敗'), 
                        data: null 
                    });
                }
            }).catch((err: any) => {
                const message = err?.data?.errorMessage || err?.message || (url + '請求失敗');
                // eslint-disable-next-line
                reject({ status: false, message, data: null});
            });
        });
    }

    /**
     * GET類型的網(wǎng)絡請求
     */
    protected getReq({ 
        baseURL, 
        headers, 
        url, 
        data, 
        params, 
        responseType 
    }: AxiosRequest) {
        return this.apiAxios({ 
            baseURL, 
            headers, 
            method: 'GET', 
            url, 
            data, 
            params, 
            responseType 
        });
    }

    /**
     * POST類型的網(wǎng)絡請求
     */
    protected postReq({ baseURL, headers, url, data, params, responseType }: AxiosRequest) {
        return this.apiAxios({ baseURL, headers, method: 'POST', url, data, params, responseType });
    }

    /**
     * PUT類型的網(wǎng)絡請求
     */
    protected putReq({ baseURL, headers, url, data, params, responseType }: AxiosRequest) {
        return this.apiAxios({ baseURL, headers, method: 'PUT', url, data, params, responseType });
    }

    /**
     * DELETE類型的網(wǎng)絡請求
     */
    protected deleteReq({ baseURL, headers, url, data, params, responseType }: AxiosRequest) {
        return this.apiAxios({ baseURL, headers, method: 'DELETE', url, data, params, responseType });
    }
}
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容