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

Next.js中间件生产环境fetch报ECONNREFUSED问题求助

Next.js中间件生产环境fetch失败的原因及解决办法

报错原因

开发模式下Next.js的dev服务器监听localhost:3000,用url.origin(即http://localhost:3000)请求内部API时,相当于本地向自身服务发起请求,能正常连通。但生产环境下情况完全不同:

  • 多数部署平台(如Vercel、容器服务)不会让应用监听localhost:3000,要么分配随机端口,要么绑定0.0.0.0这类内部地址;
  • 中间件用完整外部URL发起请求,相当于绕到网络层访问应用本身,但生产环境的应用根本没对外暴露localhost:3000这个地址,因此出现连接被拒绝的错误(ECONNREFUSED)。

解决方案

不要通过外部URL调用内部API,以下两种方式均可解决:

方式1:直接调用API逻辑函数

把/api/auth/session的代码抽成独立工具函数,比如放在lib/getSession.ts中:

// lib/getSession.ts
export async function getSession(reqHeaders: Headers) {
  // 这里写原/api/auth/session里的逻辑,比如从cookie解析session
}

然后在中间件里直接调用该函数,无需走fetch:

import { getSession } from '@/lib/getSession';

export default async function middleware(req: NextRequest) {
  const url = req.nextUrl.clone();

  if (publicPaths.some((path) => url.pathname.includes(path)))
    return NextResponse.next();

  let session;
  try {
    session = await getSession(req.headers);
  } catch (e) {
    console.error(e);
  }

  url.search = new URLSearchParams(`callbackUrl=${url}`).toString();
  url.pathname = `/api/auth/signin`;

  return session?.user ? NextResponse.next() : NextResponse.redirect(url);
}

方式2:用相对路径走内部fetch

如果坚持用fetch,Next.js支持直接用相对路径调用内部API,无需添加url.origin,此时Next.js会直接在内部处理请求,不走网络:

session = await fetch(
  `${env.NEXT_PUBLIC_APP_BASE_PATH}/api/auth/session`,
  {
    headers: req.headers,
    cache: 'no-store', // 根据业务需求调整缓存策略
  }
).then((res) => res.json());

去掉url.origin后,Next.js会自动识别这是内部API,直接调用对应处理逻辑,不会发起外部网络请求,也就不会出现连接拒绝的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 17:51:46