-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrequestConfig.ts
More file actions
135 lines (129 loc) · 3.91 KB
/
Copy pathrequestConfig.ts
File metadata and controls
135 lines (129 loc) · 3.91 KB
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { TOKEN } from '@/constants';
import storage from '@/utils/storage';
import type { RequestOptions } from '@@/plugin-request/request';
import type { RequestConfig } from '@umijs/max';
import { history } from '@umijs/max';
import { message, Modal } from 'antd';
import qs from 'qs';
// 错误处理方案: 错误类型
enum ErrorShowType {
SILENT = 0,
WARN_MESSAGE = 1,
ERROR_MESSAGE = 2,
NOTIFICATION = 3,
REDIRECT = 404,
}
// 与后端约定的响应数据格式
interface ResponseStructure {
success: boolean;
data: any;
errorCode?: number;
errorMessage?: string;
showType?: ErrorShowType;
}
/**
* @name 错误处理
* pro 自带的错误处理, 可以在这里做自己的改动
* @doc https://umijs.org/docs/max/request#配置
*/
export const requestConfig: RequestConfig = {
// 统一的请求设定
timeout: 15000,
// 错误处理: umi@3 的错误处理方案。
errorConfig: {
// 错误抛出
errorThrower: (res) => {
console.log('errorThrower', res);
const {
success = true,
data,
errorCode,
errorMessage,
showType,
} = res as unknown as ResponseStructure;
if (!success) {
const error: any = new Error(errorMessage);
error.name = 'BizError';
error.info = { errorCode, errorMessage, showType, data };
throw error; // 抛出自制的错误
}
},
// 错误接收及处理
errorHandler: (error: any, opts: any) => {
console.log('errorHandler', error, opts);
if (opts?.skipErrorHandler)
throw error;
if (error.response) {
// Axios 的错误
const { status, data } = error.response;
let errorMsg = error.statusText;
if (data) {
errorMsg = data.message || '';
}
switch (status) {
case 403:
Modal.info({
title: `登录信息已过期,请重新登录[code: ${status}]`,
okText: '重新登录',
onOk: () => {
const { search, pathname } = window.location;
storage.clear(); // 清除缓存信息
history.replace({
pathname: '/auth/login',
search: qs.stringify({
redirect: pathname + search,
}),
});
},
});
break;
default:
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
message.error(`${errorMsg || '服务器异常,请稍后重试'} ${status}`);
break;
}
}
else if (error.request) {
// 请求已经成功发起,但没有收到响应
// \`error.request\` 在浏览器中是 XMLHttpRequest 的实例,
// 而在node.js中是 http.ClientRequest 的实例
message.error('服务器暂时没有回应! 请稍后重试。');
}
else {
// 发送请求时出了点问题
message.error('请求错误,请重新尝试。');
}
throw error; // 抛出错误,方便页面进行链式调用
},
},
// 请求拦截器
requestInterceptors: [
(config: RequestOptions) => {
// 拦截请求配置,进行个性化处理。
let url = config?.url;
if (!url?.startsWith('http')) {
url = `${APP_API_HOST}${url}`;
}
// config.headers
const token = storage.get(TOKEN);
if (token) {
config.headers = {
...config.headers,
Authorization: `Bearer ${token}`.replace(/"/g, ''),
};
}
return { ...config, url };
},
],
// 响应拦截器
responseInterceptors: [
(response) => {
// 获取相应头的鉴权信息
if (Object.hasOwn(response.headers, 'token')) {
storage.set(TOKEN, response.headers.token);
}
// 拦截响应数据,进行个性化处理
return response;
},
],
};