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
相关产品推荐
相关产品推荐

