搬砖小抄

vue-vben-admin 对HTTP请求的封装

字数统计: 1.1k阅读时长: 5 min
2021/12/17 Share

vue-vben-admin 是一个中后台管理模板UI,使用vue3,vite2,TypeScript等主流技术,如果有一定的前端基础,拿来改一改就能做项目。

这是我在阅读源码时做的笔记,关于网络请求处理方面的。

HTTP请求&响应处理

请求方法封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
get<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'GET' }, options);
}

post<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'POST' }, options);
}

put<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'PUT' }, options);
}

delete<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'DELETE' }, options);
}

默认响应格式(前端预期的响应消息结构)

1
2
3
4
5
6
export interface Result<T = any> {
code: string;
type: 'success' | 'error' | 'warning';
message: string;
result: T;
}

AxiosRequestConfig

Axios请求配置,比如URL、HTTP头、超时等,还包含一些特色功能,比如下载进度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
export interface AxiosRequestConfig<D = any> {
url?: string;
method?: Method;
baseURL?: string;
// 自定义请求处理,可对请求数据和请求头加工
transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[];
// 自定义响应处理,可对响应数据和响应头加工
transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[];
headers?: AxiosRequestHeaders;
params?: any;
paramsSerializer?: (params: any) => string;
data?: D;
timeout?: number;
timeoutErrorMessage?: string;
withCredentials?: boolean;
adapter?: AxiosAdapter;
auth?: AxiosBasicCredentials;
responseType?: ResponseType;
xsrfCookieName?: string;
xsrfHeaderName?: string;
onUploadProgress?: (progressEvent: any) => void;
onDownloadProgress?: (progressEvent: any) => void;
maxContentLength?: number;
validateStatus?: ((status: number) => boolean) | null;
maxBodyLength?: number;
maxRedirects?: number;
socketPath?: string | null;
httpAgent?: any;
httpsAgent?: any;
proxy?: AxiosProxyConfig | false;
cancelToken?: CancelToken;
decompress?: boolean;
transitional?: TransitionalOptions;
signal?: AbortSignal;
insecureHTTPParser?: boolean;
}

RequestOptions

vben自定义配置项,可用对内建拦截器、钩子的行为进行定制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
export interface RequestOptions {
// Splicing request parameters to url
joinParamsToUrl?: boolean;
// Format request parameter time
formatDate?: boolean;
// 如果打开,那么直接返回响应
isTransformResponse?: boolean;
// 如果开启,那么直接返回是原生响应,调用方能够拿到HTTP状态码等信息
isReturnNativeResponse?: boolean;
// 如果打开,那么最终的请求地址为 `${urlPrefix}${config.url}`
joinPrefix?: boolean;
// 如果不为空,那么会最终请求地址会在joinPrefix的基础上加上它,最终变成`${apiUrl}${urlPrefix}${config.url}`
apiUrl?: string;
// 请求拼接路径
urlPrefix?: string;
// 出错提示 'none' 无,'modal' 弹框,'message' 弱提示(不弹框)
errorMessageMode?: ErrorMessageMode;
// 给请求加时间戳
joinTime?: boolean;
ignoreCancelToken?: boolean;
// 是否在请求头携带token
withToken?: boolean;
}

拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
export abstract class AxiosTransform {
/**
* 请求执行前钩子
*/
beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig;

/**
* 请求执行成功钩子
*/
transformRequestHook?: (res: AxiosResponse<Result>, options: RequestOptions) => any;

/**
* 请求失败钩子
*/
requestCatchHook?: (e: Error, options: RequestOptions) => Promise<any>;

/**
* 请求之前的拦截器(Axios)
*/
requestInterceptors?: (config: AxiosRequestConfig,options: CreateAxiosOptions,) => AxiosRequestConfig;

/**
* 请求之后的拦截器(Axios)
*/
responseInterceptors?: (res: AxiosResponse<any>) => AxiosResponse<any>;

/**
* 请求之前的拦截器错误处理(Axios)
*/
requestInterceptorsCatch?: (error: Error) => void;

/**
* 请求之后的拦截器错误处理(Axios)
*/
responseInterceptorsCatch?: (error: Error) => void;
}

三种钩子方法是对外部Axios调用过程的增强处理,而其他的Axios拦截器是注册到Axios实例上,在创建Axios实例时传入

内建钩子&拦截器行为梳理

默认的是实现逻辑位于 src/utils/http/axios/index.ts

请求执行前钩子 beforeRequestHook

将自定义的请求配置参数应用到Axios的配置参数上

请求执行成功钩子 transformRequestHook

  • 根据配置,决定是否进行返回码校验,拆包业务数据

  • 解析应用层响应的错误码

  • 错误消息提示、弹窗

  • 登录会话超时处理

请求失败钩子 requestCatchHook

未实现

请求之前的拦截器(Axios) requestInterceptors

在请求头中放入token,该token是登录时保存的

请求之后的拦截器(Axios) responseInterceptors

无特殊处理

请求之前的拦截器错误处理(Axios) requestInterceptorsCatch

未实现,会被外层请求失败钩子(requestCatchHook)处理

请求之后的拦截器错误处理(Axios) responseInterceptorsCatch

  • 网络错处理
  • HTTP状态码处理

此处会捕获HTTP 401错误,跳转登录页面,代码位于src/utils/http/axios/checkStatus.ts

一些技巧

在阅读源码时,发现作者对常见的HTTP请求处理做了一些优化

  • 请求方法是GET时,只需要将请求头的Content-Type设置为application/x-www-form-urlencoded;charset=UTF-8 ,那么就会使用qs库对数据进行编码。

  • 特殊情况,需要业务层自己处理HTTP响应数据时(比如某个特殊接口返回的格式比较特殊),可用设置isTransformResponse或者 isReturnNativeResponse

  • token的认证方式可用通过authenticationScheme设置,比如BaiscBear,需修改createAxios时传入的CreateAxiosOptions

CATALOG
  1. 1. HTTP请求&响应处理
    1. 1.0.1. AxiosRequestConfig
  2. 1.1. RequestOptions
  3. 1.2. 拦截器
  4. 1.3. 内建钩子&拦截器行为梳理
    1. 1.3.1. 请求执行前钩子 beforeRequestHook
    2. 1.3.2. 请求执行成功钩子 transformRequestHook
    3. 1.3.3. 请求失败钩子 requestCatchHook
    4. 1.3.4. 请求之前的拦截器(Axios) requestInterceptors
    5. 1.3.5. 请求之后的拦截器(Axios) responseInterceptors
    6. 1.3.6. 请求之前的拦截器错误处理(Axios) requestInterceptorsCatch
    7. 1.3.7. 请求之后的拦截器错误处理(Axios) responseInterceptorsCatch
  5. 1.4. 一些技巧