欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 用axios和fetch分别封装请求

用axios和fetch分别封装请求

2024/11/30 8:50:31 来源:https://blog.csdn.net/haodanzj/article/details/143921210  浏览:    关键词:用axios和fetch分别封装请求

1.axios的封装请求

import axios from "axios";
import { apiUrl } from "@/config/global-config.js";
import { useUserStore } from "../stores";
import { usePageRoute } from "@/composable/usePageRoute.js";// 创建 axios 实例
const instance = axios.create({baseURL: apiUrl,timeout: 60000,headers: { "Content-Type": "application/json" },
});// 刷新token的方法
const refreshToken = async () => {const userStore = useUserStore();try {const response = await instance.post("/auth/refresh",{},{headers: { Authorization: `Bearer ${userStore.token}` },});if (response.data.code === 200) {userStore.setToken(response.data.data.token);return true;}return false;} catch (error) {return false;}
};let isRefreshing = false; // 是否正在刷新token
let refreshSubscribers = []; // 存储等待的请求// 通知所有等待的请求
const onRefreshed = (token) => {refreshSubscribers.forEach((callback) => callback(token));refreshSubscribers = [];
};// 添加请求到等待队列
const addSubscriber = (callback) => {refreshSubscribers.push(callback);
};// 请求拦截器
instance.interceptors.request.use((config) => {const userStore = useUserStore();const token = userStore.token;if (token) {config.headers.Authorization = `Bearer ${token}`;}return config;},(error) => Promise.reject(error)
);// 响应拦截器
instance.interceptors.response.use((response) => response.data,async (error) => {const { config, response } = error;const userStore = useUserStore();if (response && response.status === 401) {// 如果刷新token请求失败,直接登出if (config.url.includes("/auth/refresh")) {await handleLogout();return Promise.reject(new Error("登录已失效"));}// 如果没有正在刷新token,开始刷新if (!isRefreshing) {isRefreshing = true;try {const refreshResult = await refreshToken();if (refreshResult) {const newToken = userStore.token;onRefreshed(newToken);config.headers.Authorization = `Bearer ${newToken}`;return instance(config);} else {await handleLogout();return Promise.reject(new Error("登录已失效"));}} finally {isRefreshing = false;}}// 返回一个Promise,将请求加入等待队列return new Promise((resolve) => {addSubscriber((token) => {config.headers.Authorization = `Bearer ${token}`;resolve(instance(config));});});}console.error("请求错误:", response.data.msg || "请求错误");return Promise.reject(error);}
);// 处理登出
const handleLogout = async () => {const userStore = useUserStore();const pageRoute = usePageRoute();const fullPagePath = pageRoute.getCurrentFullPagePath();localStorage.setItem("fullPage", fullPagePath);alert("登录已失效,请重新登录");userStore.clearToken();userStore.clearUser();setTimeout(() => {window.location.href = "/pages/login/login";}, 2000);
};// 导出GET请求方法
export const $get = (url, params, options = {}) => {return instance.get(url, { params, ...options });
};// 导出POST请求方法
export const $post = (url, data, options = {}) => {return instance.post(url, data, ...options);
};

2.fetch的封装请求

import { apiUrl } from "@/config/global-config.js";
import { useUserStore } from "../stores";
import { usePageRoute } from "@/composable/usePageRoute.js";// 刷新token的方法
const refreshToken = async () => {const userStore = useUserStore();try {const response = await fetch(`${apiUrl}/auth/refresh`, {method: "POST",headers: {"Content-Type": "application/json",Authorization: `Bearer ${userStore.token}`,},});const data = await response.json();if (data.code === 200) {userStore.setToken(data.data.token);return true;}return false;} catch (error) {return false;}
};let isRefreshing = false; // 是否正在刷新token
let refreshSubscribers = []; // 存储等待的请求// 通知所有等待的请求
const onRefreshed = (token) => {refreshSubscribers.forEach((callback) => callback(token));refreshSubscribers = [];
};// 添加请求到等待队列
const addSubscriber = (callback) => {refreshSubscribers.push(callback);
};// 处理登出
const handleLogout = async () => {const userStore = useUserStore();const pageRoute = usePageRoute();const fullPagePath = pageRoute.getCurrentFullPagePath();localStorage.setItem("fullPage", fullPagePath);alert("登录已失效,请重新登录");userStore.clearToken();userStore.clearUser();setTimeout(() => {window.location.href = "/pages/login/login";}, 2000);
};// 封装fetch请求
const fetchWithAuth = async (url, options = {}) => {const userStore = useUserStore();const token = userStore.token;const headers = {"Content-Type": "application/json",...options.headers,};if (token) {headers.Authorization = `Bearer ${token}`;}try {const response = await fetch(`${apiUrl}${url}`, {...options,headers,});if (response.status === 401) {if (!isRefreshing) {isRefreshing = true;try {const refreshResult = await refreshToken();if (refreshResult) {const newToken = userStore.token;onRefreshed(newToken);return fetchWithAuth(url, options);} else {await handleLogout();throw new Error("登录已失效");}} finally {isRefreshing = false;}}return new Promise((resolve) => {addSubscriber((token) => {options.headers.Authorization = `Bearer ${token}`;resolve(fetchWithAuth(url, options));});});}return response.json();} catch (error) {console.error("请求错误:", error.message || "请求错误");throw error;}
};// 导出GET请求方法
export const $get = (url, params, options = {}) => {const queryString = new URLSearchParams(params).toString();return fetchWithAuth(`${url}?${queryString}`, { ...options, method: "GET" });
};// 导出POST请求方法
export const $post = (url, data, options = {}) => {return fetchWithAuth(url, {...options,method: "POST",body: JSON.stringify(data),});
};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com