liveh5-nuxt/app/service/index.js

107 lines
4.0 KiB
JavaScript
Raw Normal View History

// 导入必要的模块和函数
import { useRouter } from "vue-router"; // 用于路由导航
import Request from "@/service/request/index.js"; // 自定义请求类
import { message } from '@/components/x-message/useMessage.js';
import {authStore} from "~/stores/auth/index.js"; // 消息提示组件
// 初始化路由
const router = useRouter();
let isRefreshing = false; // 标记是否正在刷新token
let refreshSubscribers = []; // 存储刷新token的回调函数
const config = useRuntimeConfig(); // 获取运行时配置
// 创建请求实例
const request = new Request({
baseURL: config.public.NUXT_PUBLIC_API_BASE, // 基础URL
timeout: 1000 * 60 * 5, // 超时时间设置为5分钟
showMsg: true, // 是否显示消息提示
interceptors: {
// 请求拦截器
requestInterceptors: (config) => {
// 根据是否是表单数据设置Content-Type
const contentType = config.isFormData ? 'multipart/form-data' : config.contentType || 'application/json';
config.headers = {
"Content-Type": contentType,
"Authorization": localStorage.getItem('token') || '' // 从本地存储获取token
};
return config; // 返回修改后的配置
},
// 响应拦截器
responseInterceptors: async (response) => {
// 如果需要显示消息且状态为1显示警告消息
if (response.config.showMsg && response.data.status === 1) {
message.warning(response.data.msg);
}
// 如果响应码为401尝试刷新token
if (response.data.code === 401) {
return getRefreshToken(response);
}
// 如果响应状态为200, 201, 204直接返回响应
if ([200, 201, 204].includes(response.status)) {
return response.config.responseType === "blob" ? response : response;
} else {
// 处理其他错误情况
const errorMsg = response.data.msg || 'An error occurred.';
message.error(errorMsg);
return Promise.reject(new Error(errorMsg));
}
},
},
});
// 刷新token的函数
async function getRefreshToken(response) {
const {token,RefreshToken,userInfo}= authStore()
if (!isRefreshing) {
isRefreshing = true; // 标记正在刷新
const refreshToken = RefreshToken.value; // 获取刷新token
if (refreshToken) {
try {
// 发送请求刷新token
const res = await request.post("/user/refresh/token", { refreshToken });
if (res.code === 200) {
// 更新本地存储的token和用户信息
token.value = res.data.Token;
userInfo.value=res.data.AccountInfo
RefreshToken.value = res.data.RefreshToken;
response.config.headers["Authorization"] = res.data.Token; // 更新请求头的token
return request.request(response.config); // 重新发送原始请求
} else {
handleAuthError(res); // 处理认证错误
}
} catch (error) {
throw error; // 抛出错误
} finally {
isRefreshing = false; // 重置刷新标记
refreshSubscribers.forEach(callback => callback()); // 执行所有等待的回调
refreshSubscribers = []; // 清空回调列表
}
} else {
handleAuthError(); // 没有刷新token时处理错误
}
} else {
// 如果正在刷新返回一个Promise等待刷新完成后重新发送请求
return new Promise(resolve => {
refreshSubscribers.push(() => resolve(request.request(response.config)));
});
}
}
// 处理认证错误的函数
function handleAuthError(res = {}) {
router.push("/login"); // 跳转到登录页面
const errorMsg = res.message || res.msg || "No refresh token available."; // 错误消息
message.error(errorMsg); // 显示错误消息
throw new Error(errorMsg); // 抛出错误
}
// 发送请求的函数
const fontRequest = (config) => {
// 如果是GET请求将data作为params
if (["get", "GET"].includes(config.method)) {
config.params = config.data;
}
return request.request(config); // 发送请求
};
export default fontRequest; // 导出请求函数