You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS动态ID API路由调用报错:无效URL问题排查

NextJS服务端调用API路由出现Invalid URL错误问题

问题背景

我基于NextJS开发项目,搭建了三层逻辑分离架构,目标是把错误处理尽可能集中在getServerSideProps中,当前需求是从数据库获取用户的所有列表数据。

第一层:API路由(运行正常)

创建了get-all-lists文件夹及[userId].js文件,请求地址为http://localhost:3000/api/get-all-lists/iudga937gr8,通过Prisma实现数据库查询,代码如下:

import prisma from '../../../lib/prisma'

export default async function handler(req, res) {
    const { userId } = req.query;

    if (req.method === 'GET') {
      try {
        const shoppingLists = await prisma.List.findMany({ where: { userId: userId }});
        res.status(200).json({lists: shoppingLists});
      } 
      catch (error) {
        console.log(error);
        res.status(500).json({ message: 'Something went wrong. Please try again'});  
      }
    }
    else {
      res.status(500).json({message: 'Invalid method requested!'});
    }
}

第二层:抽象层(触发错误)

为了避免getServerSideProps中请求代码混乱,我写了抽象层函数用于获取列表,但调用时触发URL无效错误:

export const getAllLists = async userId => {
    try {
        const lists = await axios.get(`/api/get-all-lists/${userId}`);
        return lists;    
    } 
    catch (error) {
        console.log('Abstraction layer error: ', error);
        return 'Something went wrong. Please try again later';
    }
}

问题现象

用Postman或浏览器直接访问完整URL(如http://localhost:3000/api/get-all-lists/clbcpc0hi0002sb1wsiea3q5d)能得到正确结果,但调用抽象层函数时出现如下错误:

Abstraction layer error:  TypeError [ERR_INVALID_URL]: Invalid URL
    at new NodeError (node:internal/errors:371:5)
    at onParseError (node:internal/url:552:9)
    at new URL (node:internal/url:628:5)
    at dispatchHttpRequest (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/adapters/http.js:176:20)
    at new Promise (<anonymous>)
    at http (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/adapters/http.js:112:10)
    at Axios.dispatchRequest (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/core/dispatchRequest.js:51:10)
    at Axios.request (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/core/Axios.js:142:33)
    at Axios.<computed> [as get] (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/core/Axios.js:168:17)
    at Function.wrap [as get] (file:///Users/sasdaniel/Desktop/massage/node_modules/axios/lib/helpers/bind.js:5:15) {
  input: '/api/get-all-lists/clbcpc0hi0002sb1wsiea3q5d',
  code: 'ERR_INVALID_URL'
}

解决方案

错误原因

getServerSideProps运行在Node.js服务端环境中,axios无法识别相对路径/api/xxx——浏览器会自动补全域名生成完整URL,但Node.js没有当前域名的上下文,必须传入完整URL才能正常发起请求。

修复方案1:直接调用数据库逻辑(推荐)

既然抽象层是在服务端调用,完全没必要绕路调用自己的API路由,直接复用Prisma查询逻辑,既解决URL问题又提升性能:

// 调整后的抽象层代码
import prisma from '../lib/prisma'; // 路径根据你的项目结构自行调整

export const getAllLists = async userId => {
    try {
        const shoppingLists = await prisma.List.findMany({ where: { userId }});
        return { data: { lists: shoppingLists } }; // 保持和原API返回结构一致,方便上层处理
    } 
    catch (error) {
        console.log('Abstraction layer error: ', error);
        throw new Error('Something went wrong. Please try again later'); // 抛出错误让getServerSideProps统一处理
    }
}

修复方案2:使用完整URL调用API路由

如果坚持要通过API路由获取数据,需要在抽象层中使用完整URL,建议通过环境变量配置避免硬编码:

  1. 在项目根目录的.env.local文件中添加:
NEXT_PUBLIC_BASE_URL=http://localhost:3000
  1. 修改抽象层代码:
export const getAllLists = async userId => {
    try {
        const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;
        const lists = await axios.get(`${baseUrl}/api/get-all-lists/${userId}`);
        return lists;    
    } 
    catch (error) {
        console.log('Abstraction layer error: ', error);
        throw new Error('Something went wrong. Please try again later');
    }
}

生产环境只需把NEXT_PUBLIC_BASE_URL改成你的实际域名即可。

额外提示

  • 服务端逻辑(getServerSideProps、API路由)中,优先直接调用数据库层,减少不必要的内部HTTP请求。
  • 错误处理尽量用throw代替返回字符串,这样能在getServerSideProps中统一捕获处理,符合你集中错误处理的设计目标。

内容的提问来源于stack exchange,提问作者daniel sas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 20:50:31