【问题标题】:React rendering JSON instead of component on page reload在页面重新加载时 React 渲染 JSON 而不是组件
【发布时间】:2022-01-08 00:34:29
【问题描述】:

我已经在 Heroku 上部署了我的 MERN 应用程序,一切都很好,直到我每次刷新页面或尝试从地址栏访问路由时都意识到问题。虽然通过 React Router 链接导航很好,但尝试从 URL 地址栏直接转到路由或刷新页面会导致应用程序中断并将服务器响应直接发送到浏览器而不是渲染组件 - 澄清:如果给定route 应该创建一个GET request 并显示一些数据,实际的JSON 显示在屏幕上。

据我检查,这仅发生在生成 GET request 的组件上。

server.js

// INITIATE APP
const app = express();

// MIDDLEWARE
app.use(express.json());
app.use(cookieParser());
app.use(cors());
app.use(passport.initialize());

const isProduction = process.env.NODE_ENV === "production";

// Priority serve any static files
isProduction &&
  app.use(express.static(path.resolve(__dirname, "../client/build")));

// CONNECT TO DATABASE
// db config
const dbConnection = isProduction
  ? process.env.MONGO_URI_PROD
  : process.env.MONGO_URI_DEV;

mongoose.connect(dbConnection, () => {
  console.log("Successfully connected to database");
});

// ROUTES
const authRouter = require("./routes/auth");
const detailsRouter = require("./routes/details");
const diaryRouter = require("./routes/diary");
const resultsRouter = require("./routes/results");
const settingsRouter = require("./routes/settings");

app.use("/auth", authRouter);
app.use("/details", detailsRouter);
app.use("/diary", diaryRouter);
app.use("/results", resultsRouter);
app.use("/settings", settingsRouter);

// All remaining requests return the React app, so it can handle routing
isProduction &&
  app.get("*", function (request, response) {
    response.sendFile(path.resolve(__dirname, "../client/build", "index.html"));
  });

// DEFINE PORTS
const port = process.env.PORT || 5000;

// START SERVER
app.listen(port, () => {
  console.log(`Server started on port ${port}`);
});

在上面代码的末尾,就在Define ports 之前,我包含了这条语句,以解决其他路线上发生的类似问题。我认为这将在任何情况下防止此错误,但似乎情况并非如此。可以试试here的app(测试后可以删除/settings的账号)。

【问题讨论】:

    标签: javascript node.js reactjs express


    【解决方案1】:

    我要感谢 S. Elliott Johnson 提供的解决方案,我将在下面发布给将来遇到相同问题的任何人:

    这听起来像是预期的行为。你的服务器路由和你的 React 路由器路由不应该冲突。

    React Router 实际上并不是从 HTTP 意义上“路由”到任何地方—— 它只是渲染不同的 JavaScript/HTML 并存储它的 URL 中的“位置”。

    在运行 React 应用程序时,React 应用程序通常仅从 您网站的根目录(或其他一些“根”,例如 mydomain.com/app)。当您向该路由发出HTTP GET 请求时, 后端服务器发送所有必需的 JavaScript、HTML 和 CSS 引导您的 React 应用程序。只需点击使用 React Router 使您的 React 代码在客户端上运行。

    当您实际重新加载页面时,您的浏览器会生成一个 GET 向服务器请求返回该路由,因此您只需 无论您的服务器发送什么。让我们用几个例子,你有一个 从我的 domain.com 提供的 React 应用程序。

    示例 1:

    • 用户向 mydomain.com 发出浏览器 GET 请求。他们收到 回复应用程序

    • 用户导航到/auth/login - 没有HTTP 请求,React 只是运行 代码

    • 用户导航到/me 以查看他们的帐户 -- 还是一样

    • 用户使用浏览器重新加载页面 - 发送 HTTP GET 请求 到后端,他们会收到后端发回的任何东西—— 不管是JSON 还是别的什么

    你真的有两个选择:

    1. 将所有HTTP 请求重定向到root,即/、/something 和 /anything 将服务于/。然后将您的 API 托管在另一个子域上,例如 api.mydomain.com

    2. 选择一个路由来提供您的 API,例如 mydomain.com/api。向前 来自任何路由的所有请求,除了 /api 和它的子路由到 根。

    我最终做的是选项 2:

    将我在 /api 前面的 API 路由重命名为 server.js 上的所有路由。然后我相应地重命名了 React 上的所有 API 调用。那段代码摘录

    isProduction &&
      app.get("*", function (request, response) {
        response.sendFile(path.resolve(__dirname, "../client/build", "index.html"));
      });
    

    server.js 负责处理页面刷新时执行的 GET 请求,确保 Node 始终为 index.html 提供这些请求。

    【讨论】:

      猜你喜欢
      • 2019-02-07
      • 1970-01-01
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 2017-07-14
      • 1970-01-01
      • 2018-10-07
      • 2019-10-21
      相关资源
      最近更新 更多