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

NextJS 12.2 middleware重定向受保护路由空白页报错

问题原因

Next.js 12.2+ 版本中,根目录下的middleware.js默认会拦截站点下所有请求,包括框架生成的静态资源(/_next/路径下的JS、CSS、图片资源)、公共静态文件、favicon等。
你当前的代码没有对这类静态资源做放行处理,未登录状态下浏览器请求react-refresh.js、webpack.js这类脚本资源时,也会被middleware重定向到/login路由,返回的是登录页的HTML内容。浏览器把HTML文档当作JS脚本解析,就会抛出Uncaught SyntaxError: Unexpected token '<'错误,所有脚本加载失败导致页面空白。
你之前给matcher枚举具体路由后正常,本质是因为缩小了middleware的匹配范围,没有命中静态资源路径而已。

解决方案

不需要逐一枚举所有受保护路由,只需要让middleware跳过所有不需要鉴权的静态资源、系统路径即可,两种实现方式选一种就行:

方式1:通过matcher配置排除静态路径(推荐)

Next.js的matcher支持正则负向匹配,直接配置排除所有静态资源相关路径,其余所有业务路由都会自动经过middleware处理:

// src/middleware.js
import { NextResponse } from 'next/server';

export function middleware(req) {
  const userSession = req.headers.get('cookie');
  const reqUrl = req.nextUrl.pathname;

  if (userSession?.includes('userToken')) {
    if (reqUrl.startsWith('/login')) {
      return NextResponse.redirect(new URL('/', req.url));
    }
    return NextResponse.next();
  }

  if (reqUrl.startsWith('/login')) {
    return NextResponse.next();
  };

  const loginUrl = new URL('/login', req.url);
  return NextResponse.redirect(loginUrl);
};

export const config = {
  matcher: [
    // 匹配所有路径,排除规则命中的路径
    '/((?!_next/static|_next/image|favicon.ico|/api|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)',
  ],
};

这个配置会自动跳过:

  • /_next/static、/_next/image开头的Next.js内部静态资源
  • favicon站点图标
  • /api开头的接口路径(如果接口需要走鉴权可删除这条规则)
  • 所有带静态资源后缀的文件(图片、字体、独立CSS/JS文件等)
    所有业务页面路由都会正常走鉴权逻辑,后续新增路由不需要手动逐个添加配置。

方式2:在middleware逻辑内手动放行静态资源

如果不想写matcher正则,也可以在middleware逻辑最开头增加判断,命中静态资源路径直接放行:

// src/middleware.js
import { NextResponse } from 'next/server';

export function middleware(req) {
  const { pathname } = req.nextUrl;
  // 开头直接放行所有静态资源和不需要鉴权的系统路径
  if (
    pathname.startsWith('/_next/') ||
    pathname.startsWith('/api/') || // 接口不需要鉴权可保留,否则删除
    pathname === '/favicon.ico' ||
    pathname.includes('.') // 匹配所有带后缀的静态文件
  ) {
    return NextResponse.next();
  }

  // 原有鉴权逻辑保持不变
  const userSession = req.headers.get('cookie');
  const reqUrl = pathname;

  if (userSession?.includes('userToken')) {
    if (reqUrl.startsWith('/login')) {
      return NextResponse.redirect(new URL('/', req.url));
    }
    return NextResponse.next();
  }

  if (reqUrl.startsWith('/login')) {
    return NextResponse.next();
  };

  const loginUrl = new URL('/login', req.url);
  return NextResponse.redirect(loginUrl);
};

两种方式效果完全一致,配置后静态资源会被正常返回,不会被重定向到登录页,空白和语法错误问题直接解决,同时所有新增的业务路由默认就会受鉴权逻辑保护,不需要额外配置。


内容的提问来源于stack exchange,提问作者Fer Toasted

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:36:27