【问题标题】:Stop statically served React app from calling server path停止静态服务的 React 应用程序调用服务器路径
【发布时间】:2021-11-19 02:36:21
【问题描述】:

我的应用程序的默认主页位于“/”,联系页面位于“/contact”。当我分别运行 react server(localhost:3000) 和 express server(localhost:8000) 时,这些页面之间的导航工作正常,由下面的“react-router-dom”处理。

前端 React,Routing.tsx:

import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Contact from "../pages/Contact/Contact";
import Main from "../pages/Main/Main";
import Error from "../pages/Error/Error";

function Routing() {
  return (
    <BrowserRouter>
      <Switch>
        <Route path="/error" component={Error} />
        <Route path="/contact" component={Contact} />
        <Route path="/" component={Main} />
      </Switch>
    </BrowserRouter>
  );
}

export default Routing;

现在我使用npm run build 构建了react 应用程序,并根据部署文档here 将“build”文件夹放置在我的后端快速服务器中以提供服务。然后我运行“npm run dev”来启动服务器。

但是,每当我尝试导航到 /contact 页面时,它会向“localhost:8000/contact”发出服务器调用,而不是由前端路由处理。当然,服务器不会'没有那个路由,而且我所有的服务器路由都以“/api/”开头。

我们如何防止前端导航调用服务器路由?

下面有更多代码,谢谢。

后端快递,App.ts:

import express from "express";
import path from "path";

class App {
  private _app: express.Application;
  private readonly _port: number | string = process.env.PORT || 8000;

  constructor(controllers: any[]) {
    this._app = express();
    this.initializeControllers(controllers);
    this.initializeMiddleWares();
    this.initHostingReactUI();
  }

  public start() {
    this._app.listen(this._port, () => {
      console.log(`App listening on the port ${this._port}`);
    });
  }

  private initializeControllers(controllers: any[]) {
    controllers.forEach((controller) => {
      this._app.use("/api", controller.router);
    });
  }

  public initializeMiddleWares() {
    require("./src/middleware/express.middleware")(this._app);
  }

  public initHostingReactUI() {
    // I am aware that you can do "/*" below to catch all routes, but that doesn't solve my issue as it still calls the backend for every non-api routes that should be handled by frontend routing.
    this._app.get("/", (req, res) => {
      res.sendFile(path.join(__dirname, "build", "index.html"));
    });
  }
}

export default App;

带有构建文件夹的后端文件夹结构:

如果需要:

Backend github source.

Frontend github source

【问题讨论】:

  • 使用像 nginx 这样的服务器来提供前端文件,并为所有对 /api/ 位置的调用编写代理传递指令,您应该直接表达。此外,在您的前端,它不应该在代码中使用这样的端口。

标签: node.js reactjs express react-router


【解决方案1】:

前后端路由组合有两种方式:

如果从http://localhost:3000访问

您需要同时启动前端和后端。

在这种情况下,您所有的后端请求 url 都将以 http://localhost:3000 开头(如果您没有指定基本 url)。要解决此问题,请在客户端 package.json 文件的根目录中添加一行:

{
    "proxy": "http://localhost:8000"
}

之后,前端会将所有未知路由重定向到后端。

如果从http://localhost:8000访问

你只需要启动后端。

由于 React 应用程序是一页应用程序,这意味着只有一个 html 条目(index.html)。现在我们需要一个路由来为后端的前端路由提供服务:

// place this in the end after the other routes
app.get('*', (req, res) => 
    res.sendFile(path.join(__dirname, "build", "index.html"));
})

路由系统会检查后端路由中是否存在路由。如果没有,则提供 index.html 并检查该路由是否存在于前端路由中。因此,在前端,您应该通过在未找到时返回 404 页面来保护 url。

【讨论】:

    【解决方案2】:

    您的意思是浏览应用程序吗?如果没有,通过 URL 导航到页面或刷新页面总是会向服务器发送请求,服务器应该返回 app index.js。

    您需要做的就是放置最后一条正在服务 react 的路由(您可以使用app.get('*', .....) 或放置app.use((req, res) =&gt; {...}) 而不使用路由)。

    在这种情况下,当请求到达服务器时,服务器会从上到下搜索路由,如果请求的路由不是 api 则它将为客户端应用程序提供服务。

    【讨论】:

      猜你喜欢
      • 2011-10-26
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 2018-02-03
      • 2020-06-21
      • 1970-01-01
      • 2017-04-02
      • 2019-09-05
      相关资源
      最近更新 更多