import axios from 'axios'
import type { AxiosRequestConfig } from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import 'element-plus/es/components/message-box/style/index'
import 'element-plus/es/components/message/style/index'
import { user } from '@/stores/user'
import { Menu } from '@/stores/menu'
import { ElLoading } from 'element-plus'
import 'element-plus/theme-chalk/el-loading.css'
import type { LoadingInstance } from 'element-plus/lib/components/loading/src/loading'
const request = axios.create({
baseURL: import.meta.env.VITE_API_BASEURL
})
console.log(import.meta.env)
// 请求拦截器
request.interceptors.request.use(
function (config) {
// 统一设置用户身份 token
const token = sessionStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
// config.headers.token = token
}
return config
},
function (error) {
// Do something with request error
return Promise.reject(error)
}
)
// 控制登录过期的锁
let isRefreshing = false
// 响应拦截器
request.interceptors.response.use(
function (response) {
const status = response.data.status
const code = response.data.code
if (code > 0) {
// 权限相关的报错code会大于0
ElMessage.error(response.data.message || '请求失败,请稍后重试')
return Promise.reject(response)
}
// 正确的情况
if (!status || status === 200) {
return response
}
// 错误情况:比如 token 无效...
// 其它错误情况
ElMessage.error(response.data.msg || '请求失败,请稍后重试')
// 手动返回一个 Promise 异常
return Promise.reject(response)
},
function (error) {
const errorCode =
typeof error.request.status === 'number'
? error.request.status
: error.request.status.status
if (errorCode === 401) {
// 跳转登录
if (isRefreshing) return Promise.reject(error.request)
isRefreshing = true
ElMessageBox.confirm(
'您的登录已过期,您可以取消停留在此页面,或确认重新登录',
'登录过期',
{
confirmButtonText: '确认',
cancelButtonText: '取消'
}
)
.then(() => {
// 清除本地过期的登录状态
user.$reset() // 重置状态
Menu.$reset()
// 跳转到登录页面
window.open(`跳转登录首页地址`,'_self')
})
.finally(() => {
isRefreshing = false
})
// 在内部消化掉这个业务异常
return Promise.reject(error)
} else if (errorCode === 403) {
ElMessage.error('无权限访问')
return Promise.reject(error)
}
ElMessage.error(error.message || '请求失败,请稍后重试')
return Promise.reject(error)
}
)
export default <T = any>(
config: AxiosRequestConfig,
isLoading: boolean = true,
customData = false,
rejectError = false
) => {
let loadingInstance: LoadingInstance | null
if (isLoading) {
// 默认是需要遮罩
// 设置加载遮罩
loadingInstance = ElLoading.service({
fullscreen: true,
body: true,
text: '加载中...'
})
}
return request(config)
.then((res) => {
return customData ? (res.data as T) : ((res.data.data || res.data) as T)
})
.catch((error) => {
if (rejectError) return error
})
.finally(() => {
// 最后都关闭遮罩
if (isLoading) {
loadingInstance && loadingInstance.close() // 关闭遮罩
}
})
}
Vue3.0+TS+ElementUI+登录判断拦截---请求层封装
最新推荐文章于 2024-09-04 17:19:05 发布
文章展示了如何配置axios进行请求和响应拦截,处理用户登录状态,包括设置请求头、处理401和403错误,以及在登录过期时的用户交互。同时,利用ElementPlus的组件如ElMessage和ElMessageBox提供用户体验。
摘要由CSDN通过智能技术生成