LaiToolManagementSystem/src/requestErrorConfig.ts

188 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { RequestOptions } from '@@/plugin-request/request';
import { RequestConfig, request } from '@umijs/max';
import { message } from 'antd';
import { history } from 'umi';
// 错误处理方案: 错误类型
enum ErrorShowType {
SILENT = 0,
WARN_MESSAGE = 1,
ERROR_MESSAGE = 2,
NOTIFICATION = 3,
REDIRECT = 9,
}
// 与后端约定的响应数据格式
interface ResponseStructure {
code: number;
data: any;
message?: string;
}
// 添加一个刷新 token 的函数
const refreshToken = async () => {
try {
let refreshTokenId = localStorage.getItem('refreshToken');
if (!refreshTokenId) {
return false;
}
let userId = JSON.parse(localStorage.getItem('userInfo') ?? "{}").id;
// 这里实现刷新 token 的逻辑
const response = await request('/lms/User/RefreshToken', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
data: {
refreshToken: refreshTokenId,
"userId": userId,
"deviceInfo": "2"
},
});
if (response.code == 1) {
localStorage.setItem('token', response.data);
return true;
}
return false;
} catch (error) {
console.error('刷新 token 失败', error);
return false;
}
};
const retryRequest = async (url: string, opts: RequestOptions) => {
if (url) {
try {
const response = await request(url, {
...opts,
headers: {
...opts.headers,
'Authorization': `Bearer ${localStorage.getItem('token')}`,
},
});
return response;
} catch (error) {
console.error('重试请求失败', error);
throw error;
}
} else {
throw new Error('url is required for retryRequest');
}
};
/**
* @name 错误处理
* pro 自带的错误处理, 可以在这里做自己的改动
* @doc https://umijs.org/docs/max/request#配置
*/
export const errorConfig: RequestConfig = {
// 错误处理: umi@3 的错误处理方案。
errorConfig: {
// 错误抛出
errorThrower: (res) => {
const { code, data, message } =
res as unknown as ResponseStructure;
if (code != 1) {
const error: any = new Error(message);
error.name = 'BizError';
error.info = { message };
throw error; // 抛出自制的错误
}
},
// 错误接收及处理
errorHandler: async (error: any, opts: any) => {
let url = error.config.url;
if (opts?.skipErrorHandler) throw error;
// 我们的 errorThrower 抛出的错误。
if (error.name === 'BizError') {
} else if (error.response) {
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
const { status } = error.response;
if (status === 401) {
if (url.toLowerCase().includes('/refreshtoken')) {
message.error('登录已过期,请重新登录');
localStorage.removeItem('token');
localStorage.removeItem('refreshToken');
localStorage.removeItem('userInfo');
history.push('/user/login');
} else {
// 尝试刷新 token
const refreshSuccess = await refreshToken();
if (refreshSuccess) {
// 刷新成功,重试原请求
// 这里需要实现重试逻辑,可能需要修改您的请求库
message.success('已重新获取授权,正在重试请求');
// 刷新成功,重试原请求
try {
const retryResponse = await retryRequest(url, opts);
// 如果重试成功,返回重试的响应
return retryResponse;
} catch (retryError) {
message.error('重试请求失败,请重新登录');
localStorage.removeItem('token');
localStorage.removeItem('refreshToken');
localStorage.removeItem('userInfo');
history.push('/user/login');
}
// 重试原请求的逻辑
} else {
// 刷新失败,重定向到登录页面
message.error('授权已过期,请重新登录');
localStorage.removeItem('token');
localStorage.removeItem('refreshToken');
localStorage.removeItem('userInfo');
history.push('/user/login');
}
}
// 这边要判断是不是刷新token的时候401如果是刷新token的时候401就不跳转到登录页面
// message.error('未授权,请重新登录');
// history.push('/user/login'); // 重定向到登录页面
}
} else if (error.request) {
// 请求已经成功发起,但没有收到响应
// \`error.request\` 在浏览器中是 XMLHttpRequest 的实例,
// 而在node.js中是 http.ClientRequest 的实例
message.error('None response! Please retry.');
} else {
// 发送请求时出了点问题
message.error('Request error, please retry.');
}
},
},
// 请求拦截器
requestInterceptors: [
(config: RequestOptions) => {
// 拦截请求配置,进行个性化处理。
// 添加校验头
// config.baseURL = 'https://localhost:44362';
config.baseURL = window.location.origin.includes('localhost') ? 'https://localhost:44362' : window.location.origin;
const headers = {
...config.headers, // 保留已有的请求头
'Authorization': `Bearer ${localStorage.getItem('token')}`, // 添加新的请求头
// 你可以根据需要添加更多的请求头
};
return { ...config, headers };
},
],
// 响应拦截器
responseInterceptors: [
(response) => {
// 拦截响应数据,进行个性化处理
const { data } = response as unknown as ResponseStructure;
if (data?.success === false) {
message.error('请求失败!');
}
return response;
},
],
};