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

Next.js中间件返回NextResponse.next()抛出TypeError如何解决

问题描述

我在Next.js 12.1.6版本中尝试为鉴权路由实现简易中间件,预期功能为校验认证请求头、验证令牌并根据校验结果执行对应处理逻辑。

参考公开示例的规则:

  • 放行请求需要返回NextResponse.next(),行为类似Express框架中调用next()
  • 终止请求则返回new Response()
    目前返回new Response()的拦截逻辑可正常运行,但调用NextResponse.next()时会抛出TypeError: resolver is not a function错误。

现有中间件代码

// _middleware.ts
import { NextFetchEvent, NextRequest, NextResponse } from "next/server"

const authMiddleware = async (req: NextRequest, ev: NextFetchEvent) => {
    if (validated) {
       return NextResponse.next()
     } else {
       return new Response("Unauthorized")
     } 
    }

export default authMiddleware

已尝试方案

  • 基于req.page.name调用NextResponse.rewrite()方法:动态URL场景下无法生效
  • 调用NextResponse.redirect():触发无限重定向循环

错误与环境信息

错误调用栈

Call Stack
Object.apiResolver
file:/Users/adk/Projects/myproject/nextjs/node_modules/next/dist/server/api-utils/node.js (185:15)
runMicrotasks
<anonymous>
processTicksAndRejections
node:internal/process/task_queues (96:5)
async DevServer.runApi
file:/Users/adk/Projects/myproject/nextjs/node_modules/next/dist/server/next-server.js (395:9)
async Object.fn
file:/Users/adk/Projects/myproject/nextjs/node_modules/next/dist/server/base-server.js (496:37)
async Router.execute
file:/Users/adk/Projects/myproject/nextjs/node_modules/next/dist/server/router.js (226:36)
async DevServer.run
file:/Users/adk/Projects/myproject/nextjs/node_modules/next/dist/server/base-server.js (606:29)
async DevServer.run
file:/Users/adk/Projects/myproject/nextjs/node_modules/next/dist/server/dev/next-dev-server.js (450:20)
async DevServer.handleRequest
file:/Users/adk/Projects/myproject/nextjs/node_modules/next/dist/server/base-server.js (321:20)

版本信息

  • Next.js版本:12.1.6
  • Node版本:16.15.1

项目文件结构

nextjs
├── package.json
├── next.config.js
├── tsconfig.json
├── pages
│   ├── _app.tsx
│   ├── api
│   │   └── auth
│   │       ├── _middleware.ts
│   │       └── login.tsx
│   └── index.tsx

根本原因

这个报错是Next.js 12.1.x版本的已知缺陷,和鉴权逻辑本身无关:

  • 该版本中NextResponse.next()的运行逻辑存在路径判断漏洞,仅能在普通页面路由层级的_middleware.ts中正常执行
  • 放在pages/api/**路径下的中间件调用NextResponse.next()时,运行时会错误进入API路由的处理器校验流程,找不到对应resolver函数就抛出当前错误
  • 你把鉴权中间件放在pages/api/auth/_middleware.ts路径下,刚好触发了这个bug。
修复方案

推荐方案(符合版本设计规范)

  1. 将中间件文件从pages/api/auth/目录移动到pages/根目录,或使用Next.js 12.x正式支持的根目录middleware.ts位置,该位置的中间件可以同时拦截页面路由和API路由,不会触发resolver校验错误
  2. 配置路径匹配规则,只拦截需要鉴权的接口,精准跳过login等白名单路径,避免重定向循环、动态路由rewrite失效问题。调整后的参考代码如下:
// 若使用根目录middleware.ts,需额外导出matcher配置限定作用范围
export const config = {
  matcher: '/api/auth/:path*',
}

// 中间件逻辑
import { NextFetchEvent, NextRequest, NextResponse } from "next/server"
const authMiddleware = async (req: NextRequest, ev: NextFetchEvent) => {
  // 跳过登录接口等不需要鉴权的路径
  if (req.nextUrl.pathname === '/api/auth/login') {
    return NextResponse.next()
  }
  // 替换为实际的令牌校验逻辑
  const validated = true
  if (validated) {
    return NextResponse.next()
  }
  return new Response("Unauthorized", { status: 401 })
}
export default authMiddleware
  1. 删除原pages/api/auth/路径下的旧中间件文件,重启本地开发服务即可正常运行。

临时兼容方案(不推荐)

如果不想移动中间件位置,可以在放行逻辑中不返回NextResponse.next(),直接隐式返回undefined,12.1.x版本运行时会自动继续执行后续API处理逻辑,不会触发报错。但该写法不符合Next.js中间件的标准规范,后续版本升级会直接失效。


内容的提问来源于stack exchange,提问作者ADK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 20:01:02