部署到Vercel后Next.js中间件内fetch调用相对路径API失效问题
问题根源
- Next.js的Middleware运行在Edge Runtime环境下,该环境没有默认的请求origin上下文,所以不能直接使用相对路径发起fetch请求。本地开发时Node.js环境会自动补全本地服务的origin为
http://localhost:<端口>,所以能正常运行,部署到Vercel的Edge环境后就会因为无法解析相对路径抛出你遇到的报错。 - 你遇到的问题和Middleware是否为Beta阶段无关,属于Edge Runtime的固有使用限制。另外Axios无法在Edge Runtime中正常使用也是因为其默认适配器依赖Node.js或浏览器专属的API,不属于Middleware本身的问题。
解决方法
方法1:通过请求头动态获取当前域名(更推荐,无需额外配置环境变量)
Middleware中可以直接读取到当前请求的头信息,从中获取host和协议即可拼接成完整的请求地址:
// middleware默认可以拿到入参request export default async function middleware(request) { // 从请求头获取协议和host const proto = request.headers.get('x-forwarded-proto') || 'http' const host = request.headers.get('host') // 拼接完整接口地址 const apiUrl = `${proto}://${host}/api/make-check-at-backend/` const retrievedValue = await fetch(apiUrl, { method: "POST", headers: headers, body: JSON.stringify({ someKey: 'someValue' }), }); // 后续业务逻辑 }
方法2:使用Vercel自动注入的环境变量
Vercel部署时会自动注入VERCEL_URL环境变量,值为当前部署实例的默认域名(格式如xxx.vercel.app),你可以直接读取该变量拼接完整地址:
const apiUrl = `https://${process.env.VERCEL_URL}/api/make-check-at-backend/`
如果你的应用绑定了自定义域名,建议在Vercel后台手动添加环境变量(比如NEXT_PUBLIC_APP_DOMAIN),值为你的自定义域名,使用时优先读取自定义环境变量即可。
优化建议
因为你是调用同应用下的API路由,完全可以把/api/make-check-at-backend/的核心逻辑抽离为独立的公共工具函数,直接在Middleware中调用该函数,不需要额外发起一次网络请求,能大幅提升Middleware的响应速度。
内容的提问来源于stack exchange,提问作者j4v1
相关产品推荐
相关产品推荐

