为何Next.js中间件仅在首次重定向执行?如何确保每次请求触发?
问题原因
Next.js中间件在返回重定向响应时,生产环境会默认缓存该响应结果,同时浏览器也可能缓存重定向的HTTP响应。这就导致后续对同一页面的请求直接使用缓存的重定向,不再经过中间件逻辑,直到缓存过期后才会再次执行中间件。
解决方案
要确保每次请求都执行中间件,核心是禁用重定向响应的缓存,让服务器和浏览器每次都重新处理请求。修改你的中间件代码,在返回重定向时添加缓存控制头:
import { NextRequest, NextResponse } from 'next/server'; import { cookies } from 'next/headers'; import { jwtDecode } from 'jwt-decode'; import { TokenUser } from '@/types/common/token-user.type'; export async function middleware(request: NextRequest) { console.log(request.nextUrl.pathname); const token = cookies().get('token'); if (!token) { const redirectUrl = new URL('/auth/login', request.url); const response = NextResponse.redirect(redirectUrl); // 添加缓存控制头,禁用所有缓存 response.headers.set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate'); response.headers.set('Pragma', 'no-cache'); response.headers.set('Expires', '0'); return response; } if (request.nextUrl.pathname.startsWith('/admin')) { const user = jwtDecode<TokenUser>(token.value); if (!user.isSuperAdmin) { const redirectUrl = new URL('/404', request.url); const response = NextResponse.redirect(redirectUrl); // 同样禁用缓存 response.headers.set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate'); response.headers.set('Pragma', 'no-cache'); response.headers.set('Expires', '0'); return response; } } return NextResponse.next(); } export const config = { matcher: ['/((?!api|_next/static|_next/image|auth).*)'], };
额外说明
no-store:强制浏览器和任何中间代理不存储响应内容no-cache:告诉浏览器必须先验证服务器资源是否更新,再决定是否使用缓存must-revalidate:缓存过期后必须重新向服务器验证proxy-revalidate:确保CDN等代理服务器也遵守缓存规则
开发环境下Next.js默认不会缓存中间件响应,但生产环境必须显式设置这些头才能避免缓存问题。
内容的提问来源于stack exchange,提问作者Ilya
相关产品推荐
相关产品推荐

