如何在Next.js 13中无需基础URL进行内部API调用?
问题描述
我研究Shadcn的Taxonomy项目时发现,该项目中调用内部API的fetch请求无需包含应用基础URL(比如开发环境的http://localhost:3000或生产环境的网站地址),示例代码如下:
// Get stripe checkout URL const response = await fetch("/api/users/stripe")
但我在自己的Next.js 13.4项目中复现这一行为时失败了。我的next.config文件无特殊配置,仅在.env系列文件(.env.local/.env/.env.development.local)中设置了环境变量:
NEXT_PUBLIC_APP_URL=http://localhost:3000
执行后出现错误:
请问如何实现无需基础URL即可调用内部API?
解决方案
核心原因:执行环境差异
Next.js中,服务器组件和客户端组件的fetch执行环境完全不同:
- 服务器组件的fetch在Node.js环境运行,Next.js会自动补全基础URL(开发/生产环境自动适配),因此可以直接用相对路径。
- 客户端组件的fetch在浏览器环境运行,浏览器无法解析无基础URL的纯相对路径,必须明确提供完整URL。
1. 将fetch逻辑移至服务器组件
Next.js 13+ App Router默认所有组件都是服务器组件(除非添加'use client'指令)。如果你的fetch代码写在带'use client'的组件里,移到无该指令的服务器组件中即可直接使用相对路径:
// app/SomeServerComponent.jsx async function SomeServerComponent() { const response = await fetch("/api/users/stripe") const data = await response.json() // 处理数据 }
2. 若必须在客户端组件调用
如果业务需求要求在客户端发起请求,可通过以下两种方式补全基础URL:
- 利用浏览器原生的
window.location.origin自动获取当前站点的基础URL:'use client' async function fetchStripeData() { const response = await fetch(`${window.location.origin}/api/users/stripe`) const data = await response.json() } - 使用已配置的环境变量(需确保变量以
NEXT_PUBLIC_开头,且重启开发服务器使变量生效):'use client' async function fetchStripeData() { const response = await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/users/stripe`) const data = await response.json() }
3. 检查API路由路径正确性
确保你的API路由文件路径与fetch路径匹配:
- App Router:路由文件需放在
app/api/users/stripe/route.js - Pages Router:路由文件需放在
pages/api/users/stripe.js
内容的提问来源于stack exchange,提问作者Enzo
相关产品推荐
相关产品推荐

