我的CRUD应用程序可在本地运行,但不能在Heroku上运行

时间:2020-06-06 11:41:46

标签: node.js heroku create-react-app crud

我已经创建了一个CRUD应用程序,并且可以在本地运行,但是我无法使其在heroku上正常工作。它部署正确,网站似乎正常运行,但是随后我无法从数据库中获得所需的物品,因为它一直说拒绝连接。 我将.env变量添加到了Heroku,并将端口设置为process.env.PORT || 5000app.listen(port),但不确定是什么引起了错误。我也有一个Procfile,其网址为node server.js,在package.json中有一个指向server.js的“开始”脚本。服务器似乎根本无法启动。
如果您想看一下https://github.com/ThomYorke7/inventory,请访问此处的仓库,这里是heroku https://boardgamenerd.herokuapp.com/

上的应用程序

1 个答案:

答案 0 :(得分:0)

问题在于您的应用程序具有后端(服务器)和前端(客户端),它们在本地的服务不同于在Heroku上提供的服务。

我想您的客户端在localhost:3000上运行(因为这是您引导的create-react-app的默认设置)。 当后端在localhost:5000上运行时,客户端的package.json包含以下行以使其在本地运行:

"proxy": "http://localhost:5000",

如果我访问您的应用程序的以下页面: https://boardgamenerd.herokuapp.com/>桌游, 然后我在浏览器控制台上遇到这些错误:

boardgames-list.jsx:18

Error: Network Error
    at e.exports (createError.js:16)
    at XMLHttpRequest.p.onerror (xhr.js:83)
xhr.js:178

GET http://localhost:5000/boardgames/ net::ERR_CONNECTION_REFUSED

它告诉您生产版本仍在localhost:5000上调用后端。

I。)首先,我尝试通过更改为相对URL来修复这些提取。

例如上面的示例(boardgames-list.jsx:18

您当前的脚本目前已对本地提取进行了硬编码:

useEffect(() => {
    axios
      .get('http://localhost:5000/boardgames/')
      .then((response) => {
        setBoardgames(response.data);
        setLoading(false);
      })
      .catch((err) => console.log(err));
  }, []);

✔️通过删除“ http://localhost:5000”使其相对于根:

useEffect(() => {
    axios
      .get('/boardgames/')
      .then((response) => {
        setBoardgames(response.data);
        setLoading(false);
      })
      .catch((err) => console.log(err));
  }, []);

它将在Heroku上运行。以防万一:请在下面查看我的建议。

II。)其次,一个建议: 现在,您的https://boardgamenerd.herokuapp.com/boardgames路由使用以下后端端点来获取数据:https://boardgamenerd.herokuapp.com/boardgames/

不同之处仅在于最后一个斜杠(“ /” )字符,这会造成混乱并在以后引起更多问题! 最佳做法是将差异化路径元素添加到后端端点,例如/api/。例如:https://boardgamenerd.herokuapp.com/api/boardgames因此,您可以一眼就能确定哪个GET与后端有关,哪个与客户端有关。

如果要使用此解决方案,则需要在server.js中添加以下内容:

app.use(express.static(path.join(__dirname, 'client', 'build')))
    // required to serve SPA on heroku production without routing problems; it will skip only 'api' calls
    if (process.env.NODE_ENV === 'production') {
      app.get(/^((?!(api)).)*$/, (req, res) => {
        res.sendFile(path.join(__dirname, 'client/build', 'index.html'))
      })
    }

/^((?!(api)).)*$/ regex会跳过路径中包含“ api”的URL,因此它们不会作为客户端/构建文件夹的内容被静态提供-api调用不会从静态提供并且可以正常工作。 / p>