使用Next.js中间件重定向时出现Uncaught SyntaxError错误求助
Next.js中间件重定向导致静态资源加载错误问题
问题描述
我用Next.js中间件结合Spotify API,希望在用户没有有效token时自动重定向到登录页面。中间件代码如下:
import { getToken } from "next-auth/jwt"; import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; export async function middleware(req: NextRequest) { // const token = await getToken({ req, secret: process.env.JWT_SECRET }); const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET }); const { pathname, origin } = req.nextUrl; if (pathname.includes("/api/auth") || token) { return NextResponse.next(); } // console.log(origin); // console.log(token); if (!token && pathname != "/login") { return NextResponse.redirect(new URL(`${origin}/login`)); } }
一旦注释掉下面这段重定向代码,错误就会消失,但这段代码是实现无token跳转的核心逻辑:
if (!token && pathname != "/login") { return NextResponse.redirect(new URL(`${origin}/login`)); }
我检查过语法没发现问题,但页面始终抛出以下错误:
Uncaught SyntaxError: expected expression, got '<' react-refresh.js:1 Uncaught SyntaxError: expected expression, got '<' webpack.js:1 Uncaught SyntaxError: expected expression, got '<' main.js:1 Uncaught SyntaxError: expected expression, got '<' _app.js:1 Uncaught SyntaxError: expected expression, got '<' login.js:1 Uncaught SyntaxError: expected expression, got '<' _buildManifest.js:1 Uncaught SyntaxError: expected expression, got '<'
解决方案
这个错误的根源是:中间件错误地将Next.js的静态资源文件(比如JS、CSS等)也拦截并重定向到了登录页面。浏览器原本期望加载JS文件,结果收到的是登录页面的HTML代码,解析时自然会抛出语法错误。
修复步骤
- 修改中间件逻辑,排除静态资源和Next.js内部路由:
import { getToken } from "next-auth/jwt"; import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; export async function middleware(req: NextRequest) { const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET }); const { pathname, origin } = req.nextUrl; // 跳过API认证路由、Next.js内部资源、静态文件 const shouldSkip = pathname.includes("/api/auth") || pathname.startsWith("/_next/") || pathname.startsWith("/static/") || /\.(js|css|png|jpg|svg|ico)$/.test(pathname); if (shouldSkip || token) { return NextResponse.next(); } // 仅对需要登录的页面进行重定向 if (!token && pathname !== "/login") { return NextResponse.redirect(new URL("/login", origin)); } }
- (可选)添加匹配规则,精准指定中间件需要拦截的路径:
在中间件文件末尾添加config配置,避免中间件处理不必要的路由:
export const config = { matcher: [ // 匹配所有非排除路径的路由 '/((?!api/auth|_next/static|_next/image|favicon.ico).*)', ], };
这样修改后,中间件只会拦截需要验证的页面路由,不会干扰静态资源的正常加载,错误即可解决。
内容的提问来源于stack exchange,提问作者Mohamed Nabil
相关产品推荐
相关产品推荐

