Next.js 服务器端 api 调用返回 500 内部服务器错误

Dan*_*anV 5 node.js docker reactjs server-side-rendering next.js

我终于开始涉足使用Next.js的服务器端 React 世界,但是我对这个问题感到非常困惑。

我正在使用以下方式调用pages/customer-preferences.tsxAPIisomorphic-unfetch

CustomerPreferencesPage.getInitialProps = async () => {
  const res = await fetch(API_URL + '/preference-customer');
  const initialData = await res.json();
  return { initialData };
};
Run Code Online (Sandbox Code Playgroud)

一切都可以在本地模式下正常工作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}`);
  });
});
Run Code Online (Sandbox Code Playgroud)

检查服务器日志时,我得到以下信息:

FetchError: request to http://xxx failed, reason: getaddrinfo EAI_AGAIN xxx xxx:80
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激。

cr0*_*9xx -1

fetch我的怀疑与它不是本机节点模块而是浏览器中的客户端这一事实有关。因此,如果您从一个页面导航到此页面;根据文档;getInitialProps 将从客户端调用,从而使该fetch方法可访问。刷新可确保从服务器端调用 getInitialProps。

您可以通过typeof fetch从浏览器的检查器和节点 REPL 运行来测试该理论。

您最好从组件调用该方法或使用第三方 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 };
};
Run Code Online (Sandbox Code Playgroud)