Prevent repeated submission of requests

Insert image description here
Prospect summary:
ts simply encapsulates axios, and
implements a unified API. Configure the switch interceptor
axios in config to achieve the request loading effect.

Use an array to save the URL of the current request, which has not yet responded. If the same request is made again and the URL is found to already exist in the array, the request will be intercepted and a prompt will be submitted again. When the request response ends, the url is removed from the array. Then you can initiate the request for the last url again.

Encapsulation interceptor

import {
    
     AxiosError } from "axios";
import {
    
     ElMessage } from "element-plus";
import {
    
     MyAxiosResponse, MyInternalAxiosRequestConfig } from "./request";

let pendingUrl: string[] = []; // pending 状态的请求 url
const excludeUrl: string[] = ["/upload", "/upload/chunk"]; // 排除不需要拦截的url。比如并发上传文件的 url 都是一样的,就需要排除

/**
 * 比较请求的 url
 * @param {import("..").AxiosRequestConfig} config
 * @returns
 */
export function compareUrl(config: MyInternalAxiosRequestConfig) {
    
    
    // 配置中明确标出 debounce 为 false,则关闭请求防抖。不写或者为 true,则开启防抖
    if (config.debounce === false) return config;

    // 白名单 url 不防抖处理
    if (config.url && excludeUrl.includes(config.url)) return config;

    if (config.url && pendingUrl.includes(config.url)) {
    
    
        // alert("重复请求");
        ElMessage.warning("请求频繁");
        throw new Error("请求频繁");
    } else {
    
    
        config.url && pendingUrl.push(config.url);
    }
    return config;
}

/**
 * 请求成功,过滤请求完毕的 url
 * @param {import("axios").AxiosResponse} res
 * @returns
 */
export function filterFulfilledUrlOnFulfilled(res: MyAxiosResponse) {
    
    
    pendingUrl = pendingUrl.filter(item => item != res.config.url);
    return res;
}

/**
 * 请求错误,过滤请求完毕的 url
 * @param {import("axios").AxiosError} err
 * @returns
 */
export function filterFulfilledUrlOnRejected(err: AxiosError) {
    
    
    pendingUrl = pendingUrl.filter(item => item != err?.config?.url);
    throw err;
}

Supplement config configuration and register interceptor

const DEFAULT_EXTRA_FEATURE_CONFIG = {
    
     showLoading: true, showMessage: true, debounce: true, retry: true };

/** 扩展 axios 的请求配置类型 */
export interface MyAxiosRequestConfig<TReqBodyData = any> extends AxiosRequestConfig<TReqBodyData> {
    
    
    interceptors?: {
    
    
        reqInterceptorOnFulfilled?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
        reqInterceptorOnRejected?: (err: AxiosError) => any;
        resInterceptorOnFulfilled?: (res: AxiosResponse) => AxiosResponse;
        resInterceptorOnRejected?: (err: AxiosError) => Promise<AxiosError>;
    };
    showLoading?: boolean;
    showMessage?: boolean;
    debounce?: boolean;
    retry?: boolean;
}

/** 给拦截器使用 */
export interface MyInternalAxiosRequestConfig extends InternalAxiosRequestConfig {
    
    
    showLoading?: boolean;
    showMessage?: boolean;
    debounce?: boolean;
    retry?: boolean;
}
import HttpRequest from "./http/request";
import {
    
     compareUrl, filterFulfilledUrlOnFulfilled, filterFulfilledUrlOnRejected } from "./http/debounceReq";
import {
    
     closeLoadingOnFulfilled, closeLoadingOnRejected, showLoading } from "./http/loading";
import {
    
     responseMessageOnFulfilled } from "./http/message";
import {
    
     getTokenResponseInterceptor, setAccessTokenRequestInterceptor } from "./http/token";
import {
    
     retryRequest } from "./http/retryRequest";

const httpRequest = new HttpRequest({
    
    
    baseURL: import.meta.env.VITE_APP_API_BASE_URL,
    timeout: import.meta.env.VITE_APP_API_TIMEOUT
});

// loading
httpRequest.getInstance().interceptors.request.use(showLoading);
httpRequest.getInstance().interceptors.response.use(closeLoadingOnFulfilled, closeLoadingOnRejected);

// debounceRequest
httpRequest.getInstance().interceptors.request.use(compareUrl);
httpRequest.getInstance().interceptors.response.use(filterFulfilledUrlOnFulfilled, filterFulfilledUrlOnRejected);

export default httpRequest;
``

Guess you like

Origin blog.csdn.net/qq_43220213/article/details/134194624