Nuxt 3中REST接口返回401时如何实现全局登录页跳转?
解决Nuxt 3 SSR下Axios全局401跳转问题
针对你遇到的服务端无法通过Axios拦截器跳转登录页的问题,可以通过区分服务端/客户端环境分别处理,结合Axios拦截器和Nuxt全局错误捕获来实现全局401处理:
1. 封装Axios插件,在拦截器中分层处理401
创建plugins/axios.ts,统一配置Axios并处理token刷新及401跳转:
import axios from 'axios' export default defineNuxtPlugin(() => { const api = axios.create({ baseURL: process.env.API_BASE_URL, withCredentials: true }) // 请求拦截:自动携带access token api.interceptors.request.use(config => { const accessToken = useCookie('access_token').value if (accessToken) { config.headers.Authorization = `Bearer ${accessToken}` } return config }) // 响应拦截:处理token过期与401 api.interceptors.response.use( res => res, async err => { const originalRequest = err.config // 仅处理未重试过的401请求 if (err.response?.status === 401 && !originalRequest._retry) { originalRequest._retry = true try { // 尝试用refresh token获取新access token const res = await api.post('/refresh') const newToken = res.data.accessToken // 更新access token cookie useCookie('access_token').value = newToken // 重发原请求 originalRequest.headers.Authorization = `Bearer ${newToken}` return api(originalRequest) } catch (refreshErr) { // refresh token失效,执行登录跳转 // 清除过期token useCookie('access_token').value = null useCookie('refresh_token').value = null if (process.client) { // 客户端直接用navigateTo跳转 await navigateTo('/login') } else { // 服务端通过响应头重定向 const event = useRequestEvent() if (event) { event.res.setHeader('Location', '/login') event.res.statusCode = 302 // 终止响应,避免Nuxt继续渲染页面 event.res.end() } } // 抛出错误终止Promise链 return Promise.reject(refreshErr) } } return Promise.reject(err) } ) return { provide: { axios: api } } })
2. 全局错误捕获兜底
在app.vue中添加onErrorCaptured钩子,捕获未被Axios拦截器处理的401错误(比如useAsyncData/useFetch在服务端的请求错误):
<template> <NuxtPage /> </template> <script setup> onErrorCaptured((err) => { // 判断是否为401错误 if (err.response?.status === 401) { if (process.client) { navigateTo('/login') } else { const event = useRequestEvent() if (event) { event.res.setHeader('Location', '/login') event.res.statusCode = 302 event.res.end() } } // 阻止错误继续传播 return false } return true }) </script>
关键注意事项
- 服务端不能直接用navigateTo:navigateTo是客户端导航API,服务端必须通过设置响应头
Location并终止响应来实现重定向。 - 终止服务端响应:服务端处理401时必须调用
event.res.end(),否则Nuxt会继续渲染页面,导致重定向失效。 - 避免循环请求:给原请求标记
_retry属性,防止刷新token失败后重复触发401逻辑。
内容的提问来源于stack exchange,提问作者Bjørn Stenfeldt
相关产品推荐
相关产品推荐

