在uniapp中封装请求接口 (带刷新token)

server/2024/11/14 12:40:06/
javascript">
import { apiUrl } from '@/config/global-config.js'
import { useUserStore } from '../stores'
import { usePageRoute } from "@/composable/usePageRoute.js"// 默认配置
const DEFAULT_CONFIG = {timeout: 60000,// showLoading: true,// loadingText: '加载中...'
}// 添加刷新token的方法
const refreshToken = async () => {const userStore = useUserStore()try {const response = await uni.request({url: apiUrl + '/auth/refresh',  // 替换成你的刷新token接口method: 'POST',header: {'Content-Type': 'application/json','Authorization': `Bearer ${userStore.token}`}})if (response.data.code === 200) {userStore.setToken(response.data.data.token)return true}return false} catch (error) {return false}
}// 添加一个变量来存储刷新token的Promise
let isRefreshing = false
let refreshSubscribers = []// 执行等待的请求
const onRefreshed = (token) => {refreshSubscribers.forEach(callback => callback(token))refreshSubscribers = []
}// 添加请求到队列
const addSubscriber = (callback) => {refreshSubscribers.push(callback)
}// 请求拦截器
const requestInterceptor = (config) => {const userStore = useUserStore()const token = userStore.tokenconst isMapApi = /apis\.map\.qq\.com/.test(config.url)if (token && !isMapApi) {config.header.Authorization = `Bearer ${token}`}// if (config.showLoading) {// 	uni.showLoading({ title: config.loadingText })// }return config
}// 响应拦截器
const responseInterceptor = async (response) => {const userStore = useUserStore()// const { code, msg, data } = response.dataconst code = response.data.codeconst msg = response.data.msgconst data = response.data// const data = response.data.data// console.log(data,code,msg);switch (code) {case 200:return data// return Promise.resolve(data)case 401: {// 如果是刷新token的请求失败,直接登出if (config.url.includes('/auth/refresh')) {await handleLogout()return Promise.reject(new Error('登录已失效'))}// 处理token刷新if (!isRefreshing) {isRefreshing = truetry {const refreshResult = await refreshToken()if (refreshResult) {const newToken = userStore.tokenonRefreshed(newToken)// 重试当前请求config.header.Authorization = `Bearer ${newToken}`return request(config)} else {await handleLogout()return Promise.reject(new Error('登录已失效'))}} finally {isRefreshing = false}}// 返回一个Promise,将请求暂存return new Promise((resolve) => {addSubscriber((token) => {config.header.Authorization = `Bearer ${token}`resolve(request(config))})})// 上面是刷新token 如果没有刷新token的接口直接登出  把上面的401代码注释 解开下面的两行注释//await handleLogout()//return Promise.reject(new Error('登录已失效'))}default:uni.showToast({icon: 'none',title: msg || '请求错误',duration: 2000})return Promise.reject(new Error(msg || '请求错误'))}
}// 添加统一的登出处理方法
const handleLogout = async () => {const userStore = useUserStore()const pageRoute = usePageRoute()const fullPagePath = pageRoute.getCurrentFullPagePath()uni.setStorageSync('fullPage', fullPagePath)uni.$msgBox('登录已失效,请重新登录', 2000)userStore.clearToken()userStore.clearUser()await uni.$delay(2000)uni.reLaunch({ url: '/pages/login/login' })
}// 统一请求方法
const request = (options = {}) => {const config = {...DEFAULT_CONFIG,...options,header: {'Content-Type': 'application/json',...options.header}}config.url = apiUrl + config.url// 应用请求拦截器const interceptedConfig = requestInterceptor(config)return new Promise((resolve, reject) => {uni.request({...interceptedConfig,success: async (res) => {try {const result = await responseInterceptor(res)resolve(result)} catch (error) {reject(error)}},fail: (error) => {uni.showToast({icon: 'none',title: '网络错误,请检查网络连接',duration: 2000})reject(error)},complete: () => {// if (config.showLoading) {// 	uni.hideLoading()// }}})})
}// 导出请求方法
export const $get = (url, data, options = {}) => {return request({url,data,method: 'GET',...options})
}export const $post = (url, data, options = {}) => {return request({url,data,method: 'POST',...options})
}// 挂载到全局
uni.$get = $get
uni.$post = $post

http://www.ppmy.cn/server/141592.html

相关文章

Kubernetes的基本构建块和最小可调度单元pod-0

文章目录 一,什么是pod1.1pod在k8s中使用方法(1)使用方法一(2)使用方法二 1.2pod中容器的进程1.3pod的网络隔离管理(1)pause容器的作用 1.4 Pod分类:(1)自主式…

C语言第九周课——经典算法

目录 一、冒泡法排序 1.1原理 1.2代码实现(以升序排序为例) 1.3逻辑 1.4分析 二、二分法查找 2.1原理 2.2代码实现 2.3逻辑 2.4算法效率分析 三、素数判断 3.1原理 3.2代码实现 3.3逻辑 3.4分析 一、冒泡法排序 1.1原理 冒泡排序&…

数据仓库还是数据集市?这俩怎么选?

数据仓库和数据集市作为支持决策分析的两种不同方式,根据各自的特点和优势,有不同的应用场景,今天就来探讨下数据集市和数据仓库该怎么选? 一、数据集市和数据仓库对比 1、数据集市与数据仓库的关系: 1)数…

linux进程管理

进程和线程的关系 以下介绍为linux环境 进程是操作系统中一个运行中的程序,是资源分配和调度的基本单位。每个进程有自己独立的内存空间、文件描述符、堆栈等系统资源 线程(Thread) 是 CPU 调度的最小单位,是进程中的一个执行流…

鲁棒自适应滤波,MATLAB

鲁棒自适应滤波是一种改进的信号处理技术,旨在提高滤波器在面对不确定性和动态环境变化时的性能。它结合了自适应滤波和鲁棒控制的理念,以便在有噪声或异常值的情况下更有效地估计信号。 文章目录 关键特点主要方法数学公式鲁棒性增强示例代码运行结果 总…

BY组态-低代码web可视化组件

体验地址:http://www.byzt.net:90/ 简介 BY组态是集实时数据展示、动态交互等一体的全功能可视化平台。帮助物联网、工业互联网、电力能源、水利工程、智慧农业、智慧医疗、智慧城市等场景快速实现数字孪生、大屏可视化、Web组态、SCADA等解决方案。具有实时监控、多…

pandas的to_sql方法中使用if_exists=‘replace‘

当你在pandas的to_sql方法中使用if_existsappend参数时,它会在导入数据之前删除已存在的表,然后重新创建该表,并将数据导入进去。这意味着表中的所有现有数据将被新数据完全替换。 使用 if_existsreplace 的注意事项: 数据丢失&a…

一文学习Android中的Property

在 Android 系统中,Property 是一种全局的键值对存储系统,允许不同组件和进程间以轻量级的方式进行数据传递。它主要用于系统配置、状态标识等场景,使得不同进程能够通过属性的设置或获取来通信。property 的核心特性是快速、高效&#xff0…