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

如何让Next.js的router.push()每次都经过中间件处理重定向?

问题解决:强制Next.js路由每次触发Middleware重定向

问题背景

使用Next.js客户端路由和middleware时,生产环境下router会缓存第一次的重定向结果,后续调用router.push('/')时直接跳转到缓存的目标路由,不再执行middleware逻辑。刷新浏览器后恢复正常,开发环境无此问题。需求是让router每次导航都进入middleware重新计算重定向目标。

复现步骤

  • 多次从地址栏访问/,由于middleware的随机逻辑,50%概率重定向到/dashboard,50%概率到/profile
  • 访问/login,点击Login按钮触发router.push('/'),会被重定向到其中一个路由
  • 点击Logout按钮回到/login
  • 后续每次点击Login,都会跳转到和第一次相同的路由

问题原因

Next.js生产环境的客户端路由默认对重定向结果做缓存优化,当通过router.push访问曾经重定向过的路径时,会直接复用缓存的目标地址,跳过middleware重新执行。这是生产环境的性能优化策略,但会导致动态重定向逻辑失效。

解决方案

方案1:用router.replace替代router.push

router.replace不会向history栈添加新记录,同时会绕过Next.js的重定向缓存,强制触发middleware重新计算:

// 修改login.tsx中的登录逻辑
const login = () => {
  router.replace('/')
}

方案2:添加随机查询参数绕过缓存

在跳转时给目标路径添加一个随机参数,让每次的路径“唯一”,避免缓存匹配:

// login.tsx
const login = () => {
  router.push(`/?t=${Date.now()}`)
}

同时在middleware中忽略这个随机参数,保证路径判断逻辑不受影响:

// middleware.ts
export function middleware(request: NextRequest) {
  const url = request.nextUrl.clone()
  // 移除随机参数
  url.searchParams.delete('t')
  if (url.pathname === '/') {
    if (Math.random() > 0.5) {
      return NextResponse.redirect(new URL('/dashboard', request.url))
    } else {
      return NextResponse.redirect(new URL('/profile', request.url))
    }
  }
}

方案3:禁用全局重定向缓存(不推荐)

通过Next.js配置关闭全局重定向缓存,会影响所有路由的性能,仅作为兜底方案:

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    clientRouterFilter: false,
  },
}

module.exports = nextConfig

验证效果

采用方案1或2后,每次点击Login按钮都会触发middleware重新执行随机重定向逻辑,不再复用之前的缓存结果。

内容的提问来源于stack exchange,提问作者Lautaro Riveiro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:03:21