Next.js: TypeError: Failed to parse URL from ... 当相对定位 API 路由时

Amy*_*hip 26 javascript reactjs fetch-api next.js

我的app/page(服务器组件)中有此代码:

const getUsers = async () => {
  const result = await fetch('/api/users', {method: 'GET'});
  if (result.ok) {
    return result.json();
  }
  return [];
}

export default async function IndexPage() {
  const users = await getUsers();
  return (<h1>Users: {users.length}</h1>);
}
Run Code Online (Sandbox Code Playgroud)

这给了我以下错误:

TypeError: Failed to parse URL from api/users
Run Code Online (Sandbox Code Playgroud)

如何从服务器端组件中引用 URL 的“左侧”?我能找到的所有 Next.js13示例都显示指向某个第三方服务器。Postgres 示例项目使用旧的路由器和客户端获取,使用与我使用的相同的语法。

You*_*mar 43

当您fetch(/api/users)在浏览器上使用相对路径调用时,它会起作用,因为它使用文档的来源来拥有fetch(https://your-domain.com/api/users).

然而,在发生服务器端获取的 Node.js 中,没有类似的行为。它需要一个完全定义的 URL。它与服务器组件无关,事实上,您getServerSidePropspages目录中的函数中会遇到相同的错误。

如果您愿意,可以在此GitHub Issue上阅读更多相关信息。

我建议您使用环境变量来顺利进入生产环境,其中您可能有不同的 URL。

应用程序/page.js:

const getUsers = async () => {
  const result = await fetch(process.env.URL + '/api/users', {method: 'GET'});
  if (result.ok) {
    return result.json();
  }
  return [];
}

export default async function IndexPage() {
  const users = await getUsers();
  return (<h1>Users: {users.length}</h1>);
}
Run Code Online (Sandbox Code Playgroud)

.env:

URL="http://localhost:3001"
Run Code Online (Sandbox Code Playgroud)

您只需稍后在托管服务管理中更改 URL 变量即可。


话虽如此,如果您从服务器组件调用内部 API 路由,您可能仍然会在构建时遇到另一个错误。因为那时可能还没有应用程序在运行(应用程序正在构建但尚未部署)。

Next.js 的 Tim Neutkens在这个 GitHub 问题中指出

这是因为您尝试在构建期间从内部 api 路由获取,这是不受支持的。

无需从服务器组件调用内部 API 路由,然后服务器组件调用您的 DB 或 CMS,而是直接从组件访问它们。它有助于避免错误以及额外的无用 API 调用。