如何让Nuxt自定义$fetch插件的onResponseError在刷新场景正常工作?
Nuxt自定义$fetch插件中onResponseError的异常问题
我在Nuxt中自定义$fetch并按照官方文档创建了对应插件,但遇到了onResponseError的异常问题:
- 应用会话由Nuxt Auth Utils模块管理,令牌存储在
secure中,用户信息存储在user里 - 正常场景:令牌过期时,onResponseError能正常触发——显示通知、清除会话并重定向到登录页
- 异常场景:令牌已过期时手动刷新页面,仅会显示通知,会话未被清除,也不会跳转到登录页
我的插件代码如下:
export default defineNuxtPlugin((nuxtApp) => { // 获取会话 const { clear: clearSession } = useUserSession(); const notification = useToastStore(); const api = $fetch.create({ onRequest ({ request, options, error }) { // 留空,因为令牌仅在服务端路由中获取 }, async onResponseError ({ response }) { if (response.status === 401) { // 显示通知 notification.show("Session expirée. Veuillez vous reconnecter.", "error"); // 清除会话 await clearSession(); // 跳转到登录页 await nuxtApp.runWithContext(async () => { await navigateTo('/connexion', { replace: true }); }); } }, }) return { provide: { api, }, } })
问题原因与解决方案
原因分析
手动刷新页面时,请求会在服务端执行,此时存在两个核心问题:
clearSession()在服务端调用无法直接同步清除客户端的会话状态navigateTo在服务端环境下无法直接触发客户端跳转,当前的runWithContext逻辑未适配服务端重定向场景
解决方案
修改onResponseError逻辑,区分客户端和服务端环境分别处理:
async onResponseError ({ response }) { if (response.status === 401) { // 客户端环境下处理通知、清除会话和跳转 if (process.client) { notification.show("会话已过期,请重新登录。", "error"); await clearSession(); await navigateTo('/connexion', { replace: true }); } // 服务端环境下直接返回重定向响应 if (process.server) { await clearSession(); throw createError({ statusCode: 302, statusMessage: 'Session expired', headers: { Location: '/connexion' } }); } } }
额外优化建议
- 将提示文本替换为中文,避免用户看到法语提示
- 确保
useUserSession()在服务端和客户端都能正确获取会话实例
内容的提问来源于stack exchange,提问作者MAZIKOU Franck Souverain
相关产品推荐
相关产品推荐

