Commit 5b851fbb authored by 水玉婷's avatar 水玉婷
Browse files

feat:解决401问题

parent f82cc96a
......@@ -2,6 +2,7 @@ import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { setRouter } from './utils/router-manager'
import createFetchInterceptor from './utils/fetch-interceptor'
const app = createApp(App)
app.use(router)
......@@ -9,4 +10,7 @@ app.use(router)
// 设置全局路由实例
setRouter(router)
// 启用fetch拦截器 - 自动处理401错误
createFetchInterceptor()
app.mount('#app')
\ No newline at end of file
// fetch拦截器 - 在外层处理401错误,保持组件通用性
import { navigateToLogin } from './router-manager'
// 防止重复跳转的标志
let isNavigatingToLogin = false
// 获取用户token
const getUserToken = () => {
try {
const userData = localStorage.getItem('wechat_user')
const { extMap = {} } = JSON.parse(userData || '{}')
return extMap.sessionId || ''
} catch (error) {
console.warn('解析用户信息失败', error)
return ''
}
}
// 处理401错误
const handle401Error = () => {
// 检查是否已经在跳转过程中,防止无限循环
if (isNavigatingToLogin) {
throw new Error('正在跳转到登录页面')
}
// 设置跳转标志
isNavigatingToLogin = true
// 清除本地存储的用户信息
localStorage.removeItem('wechat_user')
// 使用全局路由管理器跳转
navigateToLogin()
// 3秒后重置跳转标志,防止长时间锁定
setTimeout(() => {
isNavigatingToLogin = false
}, 3000)
throw new Error('未授权访问,请重新登录')
}
// 创建fetch拦截器
const createFetchInterceptor = () => {
// 保存原始的fetch函数
const originalFetch = window.fetch
// 拦截fetch请求
window.fetch = async function(url, options = {}) {
// 设置默认请求头
const defaultHeaders = {
'Content-Type': 'application/json',
}
// 添加认证信息
const userToken = getUserToken()
if (userToken) {
defaultHeaders['Token'] = userToken
defaultHeaders['x-session-id'] = userToken
defaultHeaders['x-app-code'] = import.meta.env.VITE_APP_CODE || ''
}
// 合并请求头
const headers = {
...defaultHeaders,
...options.headers
}
const config = {
...options,
headers
}
try {
const response = await originalFetch.call(this, url, config)
// 检查响应状态
if (response.status === 401) {
handle401Error()
}
return response
} catch (error) {
// 如果是401错误,已经处理过,直接抛出
if (error.message.includes('未授权访问')) {
throw error
}
// 其他网络错误
console.error('网络请求失败:', error)
throw error
}
}
// 返回取消拦截的方法
return {
// 恢复原始fetch
restore: () => {
window.fetch = originalFetch
},
// 获取当前拦截器状态
isIntercepted: () => window.fetch !== originalFetch
}
}
// 导出拦截器创建函数
export default createFetchInterceptor
\ No newline at end of file
......@@ -29,7 +29,7 @@ export interface MessageBlock {
// 消息类型定义
export interface Message {
messageType: 'received' | 'sent';
messageType:string;
avatar: string;
recordId: string;
promptTokens: number;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment