Next.js中间件重定向引发语法错误:unexpected token '<' 求助
问题:Next.js中间件重定向引发语法错误及页面空白的修复方案
我在Next.js应用中编写了一个中间件,用于将未认证用户重定向至登录页面。该中间件可完成重定向操作,但会导致控制台出现uncaught syntaxerror: unexpected token '<'错误,页面显示空白。修改第一个条件的第二个判断项(例如改为(!hasToken && request.url.includes('/dashboard')))即可正常运行,请问该如何修复此问题?
现有中间件代码
import { NextResponse } from "next/server"; import type { NextRequest } from 'next/server' export default function middleware(request: NextRequest) { let hasToken = request.cookies.has('token') if (!hasToken && !request.url.includes('/login')) { return NextResponse.redirect(new URL('/login', request.url)) } if (hasToken && request.url.includes('/login')) { return NextResponse.redirect(new URL('/', request.url)) } return NextResponse.next() }
控制台错误信息
uncaught syntaxerror: unexpected token '<'
问题原因
错误的核心是中间件误拦截了静态资源请求(如JS、CSS、图片等)并将其重定向到登录页。浏览器原本期望加载JS/CSS资源,结果收到的是登录页的HTML内容,试图将HTML解析为JS代码时,就会触发<符号的语法错误,最终导致页面空白。
原条件!hasToken && !request.url.includes('/login')会匹配所有非登录页的请求,包括/_next/static/下的框架静态资源、API路由请求、图标文件等,这些请求根本不需要认证保护,被重定向后自然引发错误。
修复方案
方案1:排除无需认证的公共路径
修改判断逻辑,跳过静态资源、API路由、图标等公共路径:
import { NextResponse } from "next/server"; import type { NextRequest } from 'next/server' export default function middleware(request: NextRequest) { const hasToken = request.cookies.has('token') const { pathname } = request.nextUrl // 定义无需认证的公共路径 const isPublicPath = pathname.startsWith('/_next/') || pathname.startsWith('/api/') || pathname === '/favicon.ico' || pathname === '/login' if (!hasToken && !isPublicPath) { return NextResponse.redirect(new URL('/login', request.url)) } if (hasToken && pathname === '/login') { return NextResponse.redirect(new URL('/', request.url)) } return NextResponse.next() }
方案2:明确指定需要保护的路径
如果仅需保护特定页面(如后台面板、用户中心等),直接指定这些路径即可,避免误拦截:
import { NextResponse } from "next/server"; import type { NextRequest } from 'next/server' export default function middleware(request: NextRequest) { const hasToken = request.cookies.has('token') const { pathname } = request.nextUrl // 定义需要认证才能访问的路径 const protectedPaths = ['/dashboard', '/profile', '/settings'] if (!hasToken && protectedPaths.includes(pathname)) { return NextResponse.redirect(new URL('/login', request.url)) } if (hasToken && pathname === '/login') { return NextResponse.redirect(new URL('/', request.url)) } return NextResponse.next() }
额外提示
使用request.nextUrl.pathname替代直接操作request.url更可靠,它能精准获取当前请求的路径部分,不会被URL中的查询参数、哈希值等干扰判断。
内容的提问来源于stack exchange,提问作者Pourya Tak
相关产品推荐
相关产品推荐

