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

Next.js部署Vercel遇401请求错误,寻求技术排查帮助

Vercel部署Next.js应用出现401构建错误

错误详情

构建过程中触发以下401错误,涉及/api/items和/api/items/${id}两个GET请求路由,应用未配置任何认证机制,POST请求可正常执行,推测MongoDB连接无问题:

Error [AxiosError]: Request failed with status code 401
at eO (.next/server/chunks/859.js:1:47996)
at IncomingMessage.<anonymous> (.next/server/chunks/859.js:3:9448)
at aN.request (.next/server/chunks/859.js:3:21242)
at async l (.next/server/app/items/page.js:1:8491)
at async a (.next/server/app/items/page.js:1:8595) {
code: 'ERR_BAD_REQUEST',
config: [Object],
request: [ClientRequest],
response: [Object],
status: 401,
constructor: [Function],
toJSON: [Function: toJSON]
}

相关代码片段

/items 页面组件

import axios from "axios";
import ItemCard from "@/components/ItemCard";
import { IItem } from "@/models/item.model";
import { getBaseUrl } from "@/lib/getBaseUrl";

const getData = async () => {
  try {
    const baseUrl = getBaseUrl();
    const { data } = await axios.get(`${baseUrl}/api/items`);
    console.log(data);
    // const res = await fetch("/api/items");
    // const data = await res.json();
    // console.log(data);
    return data;
  } catch (e) {
    console.log(e);
  }
};

const Items = async () => {
  try {
    const items: IItem[] = await getData();
    if (!items) {
      return <div>No items found</div>;
    }

    return (
      <div className="min-h-screen h-fit w-full bg-black flex justify-center">
        <div className="grid md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 justify-center">
          {items.map((i: IItem) => (
            <ItemCard item={i} key={i._id} />
          ))}
        </div>
      </div>
    );
  } catch (error) {
    console.error("Error loading items:", error);
    return <div>Error loading items. Please try again later.</div>;
  }
};

export default Items;

/items/${id} 页面组件

import { IItem } from "@/models/item.model";
import axios from "axios";
import { getBaseUrl } from "@/lib/getBaseUrl";

const getData = async (id: string) => {
  try {
    // const { data } = await axios.get(`/api/items/${id}`);
    // const res = await fetch(
    //   `${process.env.NEXT_PUBLIC_BACKEND_URL}/api/items/${id}`,
    //   { method: "GET" }
    // );
    // const data = await res.json();
    const baseUrl = getBaseUrl();

    const { data } = await axios.get(`${baseUrl}/api/items/${id}`);

    return data;
  } catch (e) {
    console.log(e);
  }
};

const ItemDetails = async ({ params }: { params: Promise<{ id: string }> }) => {
  const { id } = await params;
  const item: IItem = await getData(id);
  if (!item) {
    return (
      <div className="min-h-screen flex items-center justify-center text-white">
        Item not found
      </div>
    );
  }

  const date = new Date(item.date);
  return (
         {//remaining jsx here}
  );
};

export default ItemDetails;

/api/items API路由

export const GET = async () => {
  try {
    await connectToDb();
    console.log("inside get request");
    const allItems = await Item.find({});
    console.log("Successfully fetched items:", allItems.length);
    return NextResponse.json(allItems);
  } catch (error) {
    console.error("Error in GET /api/items:", error);
    return NextResponse.json(
      { error: "Failed to fetch items" },
      { status: 500 }
    );
  }
};

/api/items/${id} API路由

export const GET = async (request: NextRequest) => {
  const id = request.nextUrl.pathname.split("/").pop();
  try {
    connectToDb();
    const item = await Item.findById(id);
    return NextResponse.json(item);
  } catch (error) {
    console.log(error);
  }
};

排查与解决方案

1. 修正getBaseUrl()的使用逻辑

构建阶段(SSR/SSG)中getBaseUrl()可能返回错误域名(如本地地址),导致请求被拦截返回401。直接使用相对路径调用内部API即可,Next.js会自动处理路由解析:

// 替换原axios请求
const { data } = await axios.get("/api/items");

2. 服务器组件直接执行数据库逻辑,跳过HTTP请求

在App Router的服务器组件中,无需通过HTTP调用内部API,直接导入数据库操作函数执行查询,避免网络请求带来的环境问题:

// 修改/items页面的getData函数
import { connectToDb } from "@/lib/db";
import { Item } from "@/models/item.model";

const getData = async () => {
  try {
    await connectToDb();
    const allItems = await Item.find({});
    return allItems;
  } catch (e) {
    console.log(e);
    return [];
  }
};

3. 完善API路由的错误处理

/api/items/${id}路由中connectToDb()未加await,可能导致数据库未连接完成就执行查询,且错误分支未返回明确响应,Vercel可能默认返回401。修正后:

export const GET = async (request: NextRequest) => {
  const id = request.nextUrl.pathname.split("/").pop();
  try {
    await connectToDb(); // 添加await确保连接完成
    const item = await Item.findById(id);
    if (!item) {
      return NextResponse.json({ error: "Item not found" }, { status: 404 });
    }
    return NextResponse.json(item);
  } catch (error) {
    console.error("Error fetching item:", error);
    return NextResponse.json({ error: "Failed to fetch item" }, { status: 500 });
  }
};

4. 检查Vercel环境配置

确认Vercel后台的环境变量配置完整,查看构建日志中GET请求的执行细节,排查是否存在数据库连接异常被隐藏的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 09:08:13