Next.js 13 App Router中Axios请求添加JWT令牌问题求助
问题根源
- 模块级缓存导致令牌未更新:Axios实例初始化时就调用了
getJWTCookie(),此时如果是服务端渲染(SSR),window不存在直接返回undefined,且这个值会被缓存,后续客户端请求也不会重新获取最新的Cookie值。 - 服务端组件无法访问
document.cookie:Next.js 13 App Router的page.tsx默认是服务端组件,执行时在服务端环境,无法通过document.cookie读取浏览器Cookie,必须使用Next.js提供的服务端Cookie获取方式。
解决方案
步骤1:修改Cookie获取函数,兼容服务端环境
更新getJWTCookie,支持服务端通过Next.js的cookies()工具获取令牌:
import { cookies } from 'next/headers'; // 允许传入服务端Cookie对象,兼容服务端场景 export const getJWTCookie = (serverCookies?) => { // 服务端环境:使用传入的Cookie或next/headers的cookies() if (typeof window === 'undefined') { const cookieStore = serverCookies || cookies(); return cookieStore.get(TOKEN_KEY)?.value; } // 客户端环境:从document.cookie读取 if (!document.cookie) return undefined; return document.cookie .split('; ') .find(row => row.startsWith(TOKEN_KEY)) ?.split('=')[1]; };
步骤2:调整Axios拦截器,动态获取令牌
不要在模块初始化时缓存令牌,改为每次请求时动态获取,同时支持服务端传入令牌:
import { getJWTCookie } from "@/utils/cookie"; import axios from "axios"; const userHTTP = axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL, headers: { "Content-Type": "application/json", }, }); userHTTP.interceptors.request.use( (config) => { // 优先使用服务端传入的令牌,否则动态获取 const token = config.headers['X-Server-Token'] || getJWTCookie(); if (token) { config.headers["Authorization"] = `Bearer ${token}`; } // 删除临时头,避免传给后端 delete config.headers['X-Server-Token']; return config; }, (error) => Promise.reject(error), ); export default userHTTP;
步骤3:在API请求函数中支持传入令牌
修改getUserCart,允许接收服务端获取的令牌:
import userHTTP from "@/lib/http"; import { AxiosResponse } from "axios"; export const getUserCart = async (token?: string): Promise<IUserCart[] | undefined> => { try { const res: AxiosResponse = await userHTTP({ url: "/cart/me", method: "GET", // 服务端场景传入令牌临时头 headers: token ? { 'X-Server-Token': token } : {}, }); return res.data; } catch (e) { console.log("🚀 ~ e:", e); } };
步骤4:服务端页面中获取令牌并传入
在page.tsx(服务端组件)中,用Next.js的cookies()获取令牌,传递给API请求:
import { cookies } from 'next/headers'; import { getUserCart } from '@/path-to-your-function'; export default async function Cart() { // 服务端获取Cookie中的令牌 const token = cookies().get(TOKEN_KEY)?.value; const products = await getUserCart(token); console.log("🚀 ~ products:", products); return ( // 你的页面内容 ); }
内容的提问来源于stack exchange,提问作者FrustatedDev
相关产品推荐
相关产品推荐

