我已经创建了一个CRUD应用程序,它可以在本地运行,但我不能让它在Heroku上运行良好。 它部署正确,网站似乎工作,但然后我不能得到我需要的项目从数据库,因为它一直说连接拒绝。 我向Heroku添加了。env变量,并将端口设置为process.env.port5000
和app.listen(port)
,但我不确定是什么导致了这个错误。 我还有一个带有web:nodeServer.js
的Procfile,以及package.json中指向Server.js的“start”脚本。 服务器似乎根本就没有启动。
这里是repo,如果你想看看https://github.com/thomyorke7/inventory,这里是heroku上的app https://boardgamenerd.herokuapp.com/
问题在于您的应用程序有一个后端(服务器)和一个前端(客户机),它们在本地的服务方式与在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 fetch:
useEffect(() => {
axios
.get('http://localhost:5000/boardgames/')
.then((response) => {
setBoardgames(response.data);
setLoading(false);
})
.catch((err) => console.log(err));
}, []);
通过删除“http://localhost:5000”使其相对于root用户:
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调用不会从静态方式提供,因此可以正常工作。