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