You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:56:12