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
相关产品推荐
相关产品推荐

