GET请求返回html不是对象,路由返回不能在Heroku服务器中获得



我有一个react应用程序,使用Postman进行测试,以获得在Heroku服务器上运行的HTTP请求,客户端和服务器位于单个根文件夹中。

部署后,我在Heroku服务器上的反应路由器上遇到了一个问题,在刷新页面或手动输入端点后,我得到了一个CANNOT Get错误。为了解决这个错误,我添加了一个通配符端点来将路由重定向回server.js中的index.html(下面的代码)。

app.get('*', function (req, res) {
res.sendFile(path.join(__dirname, '../client/build', 'index.html'));
});

一旦上面的错误被修复,我又遇到了另一个问题。我现在无法通过GET request获得JSON数据,而是在邮差html.index返回。为了解决这个问题,我删除了上面的代码,然而,这个解决方案又回到了第一个错误,我陷入了一个循环,修复第一个错误并处理第二个错误。

我相信我可以写一个if语句,检查路由重定向到index.html只有在需要的时候,这是我在下面尝试过的,但它不起作用,我不确定如何写出if语句来修复这两个循环错误。

app.get("*", (req, res) => {
let url = path.join(__dirname, '../client/build', 'index.html');
if (!url.startsWith('/app/')) // <-- not sure what to replace here to make code work
url = url.substring(1);
res.sendFile(url);
});

我如何用if语句或其他解决方案处理react-router和Heroku服务器来修复这两个错误?

我的代码server.js

const mongoose = require("mongoose");
const path = require("path");
const express = require("express");
const app = express();
const cors = require("cors");
const logger = require("morgan");
const PORT = process.env.PORT || 3001;
require("./models/CalanderData"); 
const router = require("./routes/routes");
app.get("/api", (req, res) => {
res.json({ message: "Hello from server!" });
});
app.use(express.static(path.join(__dirname, '../client/build')));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use(logger("dev"));
app.get("*", (req, res) => {
let url = path.join(__dirname, '../client/build', 'index.html');
if (!url.startsWith('/app/')) // <-- not sure what to replace here to make code work
url = url.substring(1);
res.sendFile(url);
});
//MonogoDB code to access DB
app.use("/", router);
app.listen(PORT, () => {
console.log(`Express running PORT ${PORT}`);
});

routes.js

const express = require("express");
const router = express.Router();
const calDataController = require("../controllers/CalDataController");  
router.get('/get', calDataController.getData);   
// I have other routes but /get is the one I am testing 
module.exports = router;

在Create React App文档中有一个关于部署和客户端路由的方便信息。

您的Express应用程序应该有以下内容

app.use(logger("dev"));
app.use(cors()); // always register CORS before other request handling middleware
app.use(express.json()); // you only need this once
app.use(express.urlencoded()); // do you even need this?
// Register API routes
app.get("/api", (req, res) => {
res.json({ message: "Hello from server!" });
});
app.use("/", router);
// Register client routes / middleware
const CLIENT_BUILD_DIR = path.join(__dirname, "../client/build");
app.use(express.static(CLIENT_BUILD_DIR));
app.get("/*", (req, res) => {
res.sendFile(path.join(CLIENT_BUILD_DIR, "index.html"));
});

要注意的主要事情是,该捕获所有路由被定义为/*,并注册为最后。这是为了避免与其他路由冲突。

我张贴我的解决方案,这是Phils以上然而,我使用控制器,因为我不想有一堆路由在我的app.js在服务器端,所以有了这个,我需要有数据库代码之前的app.use("/", router);或应用程序中断。

就Phil的顺序而言是正确的,并且在路由请求工作之前保持MongoDB代码:)

const mongoose = require("mongoose");
const path = require("path");
const express = require("express");
const app = express();
const cors = require("cors");
const logger = require("morgan");
const PORT = process.env.PORT || 3001;
require("./models/CalanderData"); 
const router = require("./routes/routes");
app.use(logger("dev"));
app.use(cors()); // always register CORS before other request handling middleware
app.use(express.json()); // you only need this once
//MONGO DB CODE 
// Register API routes
app.get("/api", (req, res) => {
res.json({ message: "Hello from server!" });
});
// Register client routes and middleware
const CLIENT_BUILD_DIR = path.join(__dirname, '../client/build')
app.use(express.static(CLIENT_BUILD_DIR));
//notice the order here 
app.use("/", router);
app.get("/*", (req, res) => {
res.sendFile(path.join(CLIENT_BUILD_DIR, "index.html"));
});
app.listen(PORT, () => {
console.log(`Express running PORT ${PORT}`);
});