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 { joinParamsToUrl?: boolean; formatDate?: boolean; isTransformResponse?: boolean; isReturnNativeResponse?: boolean; joinPrefix?: boolean; apiUrl?: string; urlPrefix?: string; errorMessageMode?: ErrorMessageMode; joinTime?: boolean; ignoreCancelToken?: boolean; 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>;
requestInterceptors?: (config: AxiosRequestConfig,options: CreateAxiosOptions,) => AxiosRequestConfig;
responseInterceptors?: (res: AxiosResponse<any>) => AxiosResponse<any>;
requestInterceptorsCatch?: (error: Error) => void;
responseInterceptorsCatch?: (error: Error) => void; }
|
三种钩子方法是对外部Axios调用过程的增强处理,而其他的Axios拦截器是注册到Axios实例上,在创建Axios实例时传入
内建钩子&拦截器行为梳理
默认的是实现逻辑位于 src/utils/http/axios/index.ts
请求执行前钩子 beforeRequestHook
将自定义的请求配置参数应用到Axios的配置参数上
根据配置,决定是否进行返回码校验,拆包业务数据
解析应用层响应的错误码
错误消息提示、弹窗
登录会话超时处理
请求失败钩子 requestCatchHook
未实现
请求之前的拦截器(Axios) requestInterceptors
在请求头中放入token,该token是登录时保存的
请求之后的拦截器(Axios) responseInterceptors
无特殊处理
请求之前的拦截器错误处理(Axios) requestInterceptorsCatch
未实现,会被外层请求失败钩子(requestCatchHook
)处理
请求之后的拦截器错误处理(Axios) responseInterceptorsCatch
此处会捕获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
设置,比如Baisc
、Bear
,需修改createAxios
时传入的CreateAxiosOptions