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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:42:53