| 问题描述 | 偶尔会出现未授权获取数据的问题。 |
| 所属模块 | 项目信息查询 |
| 严重程度 | 一般 |
| 涉及类型 | 全部类型 |
| 提出人 | 刘向诚 |
| 处理人 / 状态 | 待指派 / 2.1.待开发 |

newEnergySwTHWeb 门户壳加载,见 URL 中的 /business-page/newEnergySwTHWeb/... 前缀),即认证失败的统一提示是壳应用或 API 网关的全局响应拦截器加上去的,不在 xnybw5f 本身的代码范围内。xnybw5f 本身能控制的部分:src/utils/request.js 第 40-115 行,axios 请求/响应拦截器:
service.interceptors.request.use(async (config) => {
...
const authMode = getAuthMode()
const token = getToken()
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
...
}
return config
})
service.interceptors.response.use(
(response) => { ... },
(error) => {
console.log(`err${error}`)
Message({ message: error.message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
)
getToken() 取到的 token 塞进 Authorization 头,没有任何 401 重试/刷新机制——响应拦截器收到错误(含 401)只是弹一条通用错误提示并 reject,既不会尝试静默刷新 token 再重发请求,也不会对"并发多个请求同时因 token 过期/尚未写入而失败"的场景做请求排队。这意味着如果根因是 token 处于"即将过期 / SSO 会话刚续期但本地还没来得及更新"的竞态窗口,xnybw5f 前端目前完全没有自愈能力,每一次落在这个窗口内的请求都会直接失败给用户看到"未授权",这与"偶尔"复现的现象吻合。let isRefreshing = false
let pendingQueue = [] // 401 期间到达的请求,等刷新完成后统一重放
service.interceptors.response.use(
(response) => { ... },
async (error) => {
const { config, response } = error
if (response && response.status === 401 && !config._retried) {
if (!isRefreshing) {
isRefreshing = true
try {
await refreshToken() // 需要认证模块提供静默刷新能力
pendingQueue.forEach(cb => cb())
pendingQueue = []
} catch (e) {
pendingQueue = []
Message({ message: '登录已过期,请重新登录', type: 'error' })
redirectToLogin()
return Promise.reject(error)
} finally {
isRefreshing = false
}
}
return new Promise((resolve) => {
pendingQueue.push(() => {
config._retried = true
resolve(service(config))
})
})
}
Message({ message: error.message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
)