【问题标题】:My CRUD app works locally but not on Heroku我的 CRUD 应用程序可以在本地运行,但不能在 Heroku 上运行
【发布时间】:2020-06-06 20:47:06
【问题描述】:

我创建了一个 CRUD 应用程序,它可以在本地运行,但我无法让它在 heroku 上正常运行。它部署正确,网站似乎可以工作,但是我无法从数据库中获取我需要的项目,因为它一直说连接被拒绝。 我将 .env 变量添加到 Heroku,并将端口设置为 process.env.PORT || 5000app.listen(port),我不确定是什么导致了错误。我还有一个带有 web 的 Procfile:node server.js,以及 package.json 中指向 server.js 的“启动”脚本。服务器似乎根本没有启动。
这里是 repo,如果你想看看 https://github.com/ThomYorke7/inventory,这里是 heroku 上的应用程序 https://boardgamenerd.herokuapp.com/

【问题讨论】:

  • 您是否确认您实际上正在尝试连接到正确的数据库服务器?
  • 你可以尝试从本地连接到远程数据库服务器吗?
  • 当我在 VS Code 中本地运行“node server.js”时,我得到两个 console.log,一个来自 connection.once(open, () => console.log("Connected to database"),另一个来自 app.listen(port, ()=> console.log("The server is running on: ${port}")。后者在控制台中显示端口 5000。所以是的,我想我可以从本地连接。
  • 欢迎来到 Stack Overflow。请使用tour 并阅读How to Ask。问题必须是独立的;我们不会离开现场并挖掘您的代码以寻找问题。请edit相关信息直接进入您的问题。

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


【解决方案1】:

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

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

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

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

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

您当前的脚本目前已硬编码 localhost 获取:

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)).)*$/ 正则表达式会跳过路径中包含“api”的 URL,因此它们不会作为客户端/构建文件夹的内容静态提供 - api 调用不会从静态提供并且可以正常工作。

【讨论】:

  • 非常感谢您的回复!我知道问题可能在于“硬编码”获取路径,但我不知道如何使它们相对。但是,现在我面临两个新问题。首先,当我添加差异化路径时,我下载和显示项目的页面变为空白。我想是因为我必须编辑在某处添加 /api 的路径,但我不知道确切的位置(无论是单个路由还是 server.js)。第二点是当我尝试添加/删除或编辑数据库项目时,网站的行为很奇怪,显示来自数据库的原始数据。
  • 是的,一旦 (I) 您需要在 server.js 中进行端点更改,例如:app.use('/api/boardgames', boardgamesRouter);(II) 不要忘记在 React 组件的 fetch 中获取这些新端点上的数据,例如:axios.get('/api/boardgames/')。这是在后端端点路径中使用 /api/ 的两个关键点。它可能需要对后端路由进行微调,您可能需要重构一些其他快速中间件以使其工作(expressjs.com/en/guide/using-middleware.html)。 编辑:我修复了示例中的路径和拼写错误。
  • @ThomYorke 你能修复路径吗?
  • 是的,我做到了。我在粘贴你建议的 sn-p 时遇到了困难,因为它是一个中间件,没有编辑我的 app.get('*') 行。然后我意识到 sn-p 基本上是一个有条件的 app.get 并且我粘贴在正确的位置。现在我认为一切正常,非常感谢您的帮助。
  • 很高兴听到,我很高兴它有帮助。
猜你喜欢
  • 2021-09-18
  • 1970-01-01
  • 2018-06-10
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
  • 2016-06-19
  • 2013-08-08
  • 1970-01-01
相关资源
最近更新 更多