Next.js lib层fetch调用内部API路由报错问题求解
问题原因
- 第一个
TypeError: Only absolute URLs are supported报错:cross-fetch在Node.js环境执行时没有浏览器默认的origin上下文,不支持相对路径请求,且package.json配置的proxy仅对浏览器端发起的请求生效,对Node端请求无效。 - 第二个
ECONNREFUSED报错:你直接执行lib文件测试时,本地Next.js开发服务未启动,3000端口没有进程监听,自然无法建立连接;此外你在模块顶层直接写了fetchCityData('London'),如果项目启动时就导入这个模块,请求会在服务启动完成前发起,也会触发该报错。
可行解决方案
1. 先调整lib/cityData.js代码
删除模块顶层的测试调用,从环境变量读取站点根地址拼接请求路径,优化异步处理逻辑,修改后代码如下:
const fetch = require('cross-fetch'); // 优先取环境变量里的站点地址,本地开发默认 fallback 为localhost:3000 const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'; const fetchCityData = async (city) => { const options = { method: `POST`, }; try { const response = await fetch(`${BASE_URL}/api/weather?city=${city}`, options) if(response.ok){ const data = await response.json() console.log(data) return data } throw new Error('Api is not available') } catch(error) { console.error('Error fetching data: ', error) throw error } } module.exports.fetchCityData = fetchCityData;
2. 配置环境变量
在你的.env.local文件中添加对应变量,注意如果该方法需要在客户端组件调用,变量名必须加NEXT_PUBLIC_前缀,才能被客户端代码读取:
# 开发环境地址 NEXT_PUBLIC_SITE_URL=http://localhost:3000 # 生产环境可以替换为你的线上域名,比如 https://your-domain.com
3. 正确测试/调用方法
- 本地单独测试该lib文件:先执行
npm run dev启动Next.js开发服务,再新开一个终端执行node -e "require('./lib/cityData').fetchCityData('London')"测试即可,不要直接在模块代码里写死调用逻辑。 - 组件内调用:直接导入方法即可,客户端/服务端场景都能自动适配环境变量的地址。
- 额外注意:确认你的
pages/api/weather.js(或app router下的对应路由)已经实现了POST方法的处理逻辑,否则连通后会返回405方法不允许错误。
内容的提问来源于stack exchange,提问作者Katharina Schreiber
相关产品推荐
相关产品推荐

