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

NextJS中间件触发NetworkError求助:如何排除自身请求

解决Next.js中间件导致的NetworkError及未登录重定向问题

问题背景

按照旧教程编写的Next.js中间件,目标是实现未登录/会话过期时访问任意页面重定向到登录页,但运行时触发TypeError: NetworkError when attempting to fetch resource。排查后确认是中间件拦截了Next.js或webpack的内部请求(如静态资源、打包产物),这些请求被强制重定向后导致页面资源加载失败。

错误原因

原代码仅放行/api/auth路径和已登录用户的请求,但Next.js的内部资源请求(如/_next/static/、/_next/webpack-hmr等)、站点图标/favicon.ico等静态文件请求没有token,会被触发重定向逻辑,导致资源无法正常加载,进而引发网络错误。此前添加的/_next/排除逻辑因位置错误,没有起到作用。

解决方案

调整中间件的判断顺序,优先放行Next.js内部资源和静态文件请求,再处理认证相关逻辑:

  • 先放行/_next/开头的所有请求(覆盖Next.js打包产物、热更新等内部资源)
  • 放行/favicon.ico这类常见静态文件
  • 放行NextAuth的认证接口/api/auth
  • 已登录用户(存在token)直接放行所有请求
  • 未登录且当前路径不是登录页时,重定向到登录页

修正后的完整代码

import { getToken } from "next-auth/jwt";
import { NextResponse } from "next/server";

export async function middleware(req) {
  const url = req.nextUrl.clone();
  const { pathname } = req.nextUrl;

  // 优先放行Next.js内部资源和静态文件,避免拦截导致资源加载失败
  if (pathname.startsWith("/_next/") || pathname === "/favicon.ico") {
    return NextResponse.next();
  }

  // 放行NextAuth认证相关接口
  if (pathname.includes("/api/auth")) {
    return NextResponse.next();
  }

  // 获取用户登录状态
  const token = await getToken({ req, secret: process.env.JWT_SECRET });

  // 已登录用户直接放行
  if (token) {
    return NextResponse.next();
  }

  // 未登录且当前不在登录页,重定向到登录页
  if (!token && pathname !== "/login") {
    url.pathname = "/login";
    return NextResponse.redirect(url);
  }

  // 兜底放行(登录页请求)
  return NextResponse.next();
}

关键说明

  • 把内部资源的判断放在最前面,确保这类请求不会进入后续的认证逻辑
  • 使用pathname.startsWith("/_next/")更精准匹配Next.js内部资源路径,避免遗漏子路径
  • 重定向时直接修改url.pathname再调用NextResponse.redirect(url),避免拼接字符串可能出现的域名格式问题
  • 确保环境变量JWT_SECRET已正确配置,且/login页面已存在,避免循环重定向

内容的提问来源于stack exchange,提问作者Kağan Ahmet Okan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:42:22