Next.js 服务器端 api 调用返回 500 内部服务器错误
Posted
技术标签:
【中文标题】Next.js 服务器端 api 调用返回 500 内部服务器错误【英文标题】:Next.js server side api call returns 500 internal server error 【发布时间】:2020-05-10 07:07:12 【问题描述】:我终于开始涉足使用Next.js 进行服务器端反应的世界,但是我对这个问题感到很困惑。
我正在使用 isomorphic-unfetch
从 pages/customer-preferences.tsx
调用 API
CustomerPreferencesPage.getInitialProps = async () =>
const res = await fetch(API_URL + '/preference-customer');
const initialData = await res.json();
return initialData ;
;
在dev
模式下或一旦构建并运行build
> start
,一切都可以正常工作。为了托管它,我从 docker 容器 node:10
运行它,当我在本地运行它时,一切都很好。该问题仅在部署后才会发生。
当我导航到/
,然后单击指向/customer-preferences
的链接时,一切都按预期工作。但是,如果我刷新页面或直接在 /customer-preferences
加载页面,我会从 Next.js 看到此错误
所以这个问题似乎只发生在尝试从服务器而不是客户端进行 API 调用时。
我还设置了一个简单的快速服务器来代替使用,但不确定是否有必要?!
const express = require('express');
const next = require('next');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next( dev );
const handle = app.getRequestHandler();
app.prepare().then(() =>
const server = express();
server.all('*', (req, res) =>
return handle(req, res);
);
server.listen(port, err =>
if (err) throw err;
console.log(`> Ready on http://localhost:$port`);
);
);
当检查服务器日志时,我得到了这个:
FetchError: request to http://xxx failed, reason: getaddrinfo EAI_AGAIN xxx xxx:80
任何帮助将不胜感激。
【问题讨论】:
这对您有帮助吗? github.com/nodejs/node/issues/15780#issuecomment-425930255 @MichalisGarganourakis 是的,看到了,但该线程上也没有任何回应 @xadm 我需要一个混合应用程序。这适用于完全静态的应用程序 不要使用绝对 URL,使用可以解决问题的相对 URL @divyang4481 API 与应用无关 【参考方案1】:我的怀疑与fetch
不是本机节点模块而是浏览器中的客户端这一事实有关。所以,如果你从一个页面导航到这个页面;根据文件; getInitialProps 将从客户端调用,使fetch
方法可访问。刷新确保从服务器端调用的 getInitialProps。
您可以通过从浏览器的检查器和节点 REPL 运行 typeof fetch
来测试这个理论。
您最好从组件调用方法或使用第三方 HTTP 客户端,如 axios
...
如果你想跳过从后端调用 AJAX 方法而只从前端调用它,你可以测试该方法是从前端调用还是从后端调用,如下所示:
CustomerPreferencesPage.getInitialProps = async () =>
if (typeof window === 'undefined')
// this is being called from the backend, no need to show anything
return initialData: null ;
const res = await fetch(API_URL + '/preference-customer');
const initialData = await res.json();
return initialData ;
;
【讨论】:
I'm making a call to an API from pages/customer-preferences.tsx using isomorphic-unfetch
@cr05s19xx 不完全是。同构 是 这里的罪魁祸首,但这与模块导入无关。问题是getInitialProps
是同构的,因此在客户端和服务器上调用 Docker 主机名。主机名在客户端公开为 localhost。【参考方案2】:
不,不需要服务器设置。
发生这种情况是因为浏览器/客户端无法解析 docker 容器的主机名。就目前而言,我知道的唯一解决方案是检查 getInitialProps
中的 req 对象(以确定提取将在哪个环境中运行)并在服务器上调用 Docker 主机名,在客户端调用 localhost。例如。
async getInitialProps (ctx)
if (ctx.req) // ctx.req exists server-side only
// call docker-host:port
else
// call localhost:port
【讨论】:
以上是关于Next.js 服务器端 api 调用返回 500 内部服务器错误的主要内容,如果未能解决你的问题,请参考以下文章
Next.js 500 内部服务器错误在 404 页面内调用 useEffect Hook 后立即出现
如何处理调用 API 的 Next.js 中动态路由的未找到 404?