NextJS 13 Server Component Fetch无法触发API端点的问题
Next.js 13 App Router API调用不触发问题解决
问题场景
使用Next.js 13 App Router时,在app/protected/paymo/viewer/[id]/page.tsx的服务器组件中通过fetchForm函数调用内部API,控制台能打印正确的请求地址,但API路由app/api/paymo/[id]/route.ts中的日志未输出,API未被触发;直接在浏览器地址栏访问该API URL则正常响应。
相关代码如下:
页面组件代码(page.tsx)
async function fetchForm(id: string) { const endpoint = `${process.env.NEXT_PUBLIC_URL}/api/paymo/${id}` console.log("endpoint: ", endpoint); const response = await fetch(endpoint, { next: { revalidate: 0 } }); return await response.json(); } const FormPage = async ( { params }: { params: { id: string } } ) => { const id = params.id; const data = await fetchForm(id); console.log("data: ", data); // 组件其余逻辑 }
API路由代码(route.ts)
export async function GET( request: Request, { params }: { params: { id: string } } ) { const paymoId = params.id; console.log(`GET /api/paymo/${paymoId}`); console.log("API PAYMO GET"); // 数据返回逻辑 }
解决方案
问题根源在于服务器组件中使用完整外部URL调用内部API,Next.js在服务器端处理fetch时,对于完整URL会走外部网络请求,而本地开发环境可能存在请求转发或缓存问题,导致API未被正确触发。
修改fetchForm函数,使用相对路径调用API即可解决:
async function fetchForm(id: string) { // 替换为相对路径,无需依赖环境变量的完整URL const endpoint = `/api/paymo/${id}` console.log("endpoint: ", endpoint); const response = await fetch(endpoint, { next: { revalidate: 0 } }); // 推荐添加错误处理,避免请求失败导致页面崩溃 if (!response.ok) { throw new Error(`API请求失败,状态码:${response.status}`); } return await response.json(); }
补充说明
- 在App Router的服务器组件中,使用相对路径调用
fetch时,Next.js会直接调用对应API路由的处理函数,无需走HTTP网络请求,性能更优。 - 若因特殊需求必须使用完整URL,可检查本地开发环境的网络配置,同时尝试移除
next: { revalidate: 0 }测试是否为缓存问题,但优先推荐使用相对路径。
内容的提问来源于stack exchange,提问作者Brian Lee
相关产品推荐
相关产品推荐

