【问题标题】:Nginx and Create React App (with React Router) full routes not workingNginx 和创建 React 应用程序(使用 React 路由器)完整路由不起作用
【发布时间】:2020-11-21 00:36:15
【问题描述】:

我已经被这个问题困扰了好几天了,我需要互联网的帮助。

我为我的 React 应用程序创建了一个静态 HTML 登录页面项目(这两个项目是分开的),我希望使用 Nginx 为这两个项目提供服务。我的登录页面项目有自己的目录结构和资产,如下所示:

/homepage
--index.html
--contact.html
--about-us.html
  /static
   --css files, imgs, ect

我的 React 应用程序是一个 Create React 应用程序,据我了解,在您运行 npm build 后,它会为您提供一个名为 build 的文件夹,其中包含正确捆绑的所有项目文件,以便您可以部署它。现在我有两个目录,其中包含为网站提供服务所需的所有内容,但使用 Nginx 很难做到这一点。

我希望我的登陆页面位于 / 所以 www.example.comwww.example.com/contact 等会导致我的登陆页面项目,然后 www.example.com/appwww.example.com/app/login 等会导致我的反应项目。

我的 Nginx 配置如下所示:

# redirect to https
server {
  listen        80;

  server_name   _;

  return 301 https://$host$request_uri;
}

server{
    listen 443 ssl;
    ssl_certificate /etc/nginx/certs/localhost.pem;
    ssl_certificate_key /etc/nginx/certs/localhost-key.pem;
    proxy_cookie_path / "/; HTTPOnly; Secure";

    location / {
        root /usr/share/nginx/html/homepage/;
        try_files  $uri.html $uri $uri/ =404;
    }

    location /app/ {
        alias /usr/share/nginx/html/app/;
        try_files  $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass          http://backend:8080/;
    }

}

我可以正确查看我的 react 应用程序主页,但是当我导航到任何其他页面时,例如 https://localhost/app/test,我会被发送到一个损坏的登录页面的 index.html(所有链接/样式坏了)。因此,链接 https://localhost/app 将我定向到我的 react 应用程序的 index.html,但是当我转到 https://localhost/app/test 时它已损坏,它给了我登录页面损坏的 index.html

如何正确配置 nginx 以在我的登录页面项目旁边为我的 react 应用程序的其他路由提供服务?

编辑:

有关更多信息,我添加了一个事实,即我在我的 react 应用程序中使用 React 路由器,并且我的 index.tsx 看起来像这样:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import * as serviceWorker from "./serviceWorker";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";
import Home from "./components/Home";
import Login from "./components/Login/Login";
import Dashboard from "./components/Dashboard";
import SignupPage from "./components/Signup/SignupPage";
import DashNavbar from "./components/DashNavbar";
import PersonCard from "./components/PersonCard/PersonCard";
import AnalyticsSmallCard from "./components/AnalyticsSmallCard";
import Test2 from "./components/Test2";
import Test from "./components/Test";
import PrivateRoute from "./components/PrivateRoute";
import NotesSideBar from "./components/NotesSideBar";
import NotesPage from "./components/NotesPage";
import WarningCard from "./components/WarningCard";

const App = (
  <Router basename="/app">
    <Switch>
      <Route path="/" component={Home} />
      <Route path="/login" component={Login} />
      <Route path="/signup" component={SignupPage} />
      <PrivateRoute exact path="/dashboard" component={Dashboard} />
      <Route path="/test" component={WarningCard} />
    </Switch>
  </Router>
);

ReactDOM.render(App, document.getElementById("root"));

serviceWorker.unregister();

【问题讨论】:

    标签: javascript reactjs nginx deployment react-router


    【解决方案1】:

    网络服务器,“提供”文件。当你访问example.com/app时,网络服务器只显示/usr/share/nginx/html/app/index.html中的内容,同样如果你访问example.com/app/login,它会尝试显示/usr/share/nginx/html/app/login/index.html中的内容

    在没有看到或不知道您是如何构建 React 应用的情况下,很难知道问题出在哪里。 React,当你构建时,只会在构建目录中创建单个 index.html 以及一堆 javascript。

    这就是为什么你可以在你的 react 主页上看到它 (www.example.com/app)。但是当您导航到 example.com/app/login 时,您不能。因为 /app 有一个 index.html,但 /app/login 没有。 Nginx 期望 /app/login 目录下有一个 .html 文件。

    快速解决方案: 大多数人会使用 React Router 来创建一个多页面的 React 应用程序。这允许您在 react 应用程序中拥有路由。

    即使你只有一个 index.html,你也可以使用 react-router 创建不同的“页面”,这一切都由内置的 javascript 处理,你不必担心在 Nginx 中创建一堆路由。只需路由到 react 主应用程序,react-router 将处理其余的!

    【讨论】:

      【解决方案2】:

      正如@codebytesfl 提到的,您需要让 nginx 为 /app/ 下的所有路径返回反应应用程序 index.html(因为您的反应应用程序在 客户端 端处理路由)。

      我认为根本原因是alias指令的使用。

      try_files$uri 附加到已经用alias 设置的路径上。 更多详情read this

      尝试将alias 更改为root

          location /app/ {
              root /usr/share/nginx/html/app/;
              try_files $uri $uri/ /index.html;
          }
      
      

      【讨论】:

      • 这个解决方案不起作用(我试过),我认为这是因为如果你看这个答案stackoverflow.com/questions/10631933/…。该根指令将指向 /usr/share/nginx/html/app/app 如果我将其更改为根 /usr/share/nginx/html/ 它将适用于第一个组件,但我的反应应用程序上的所有其他路由仍然坏了,所以我遇到了同样的问题
      【解决方案3】:

      我目前在项目中使用此功能的方式是在 React 应用程序的 package.json 文件中添加一个 homepage 字段。

      {
        "name": "react-app-name",
        ...dependencies and such
      
        "development": [
            "last 1 chrome version",
            "last 1 firefox version",
            "last 1 safari version"
          ]
        },
        "homepage": "https://example.com/app",
        "proxy": "https://example.com/api"
      }
      

      除了Router 组件中已有的basename 属性之外,您还需要此属性。这应该允许您通过 React Router 呈现这些页面。如果你能看到example.com/app,我假设你的 NGINX 文件中的路径是正确的。

      【讨论】:

      • 我认为 nginx 中的路径不正确。我已经做了你上面提出的步骤。该应用程序运行良好,否则它只是通过 /app 的其他路径,如 /app/login/test 将中断
      • 您是否尝试过在您的location /app/ 块中设置rootindex 指令?例如root /usr/share/nginx/html/;,然后在下一行index index.html index.htm;
      • 我可以尝试使用 root 来代替它,为什么它应该是 root 而不是别名?
      • 只要路径设置正确,使用哪一个似乎并不重要。我常用root,因为它更简洁一些。
      【解决方案4】:

      检查您的 index.html。如果包含 &lt;base href="/"&gt; ,请将其替换为 &lt;base href=""&gt;

      【讨论】:

      • 你说的是生成的react index.html吗?
      • 请检查,该 index.html 中 href 的值是多少
      • 他们在谈论你公共目录中的index.html
      【解决方案5】:

      我认为你的

      <Route path="/" component={Home} />
      

      应该是

      <Route exact path="/" component={Home} />
      

      否则交换机将始终命中该路由并忽略其余部分。

      【讨论】:

        【解决方案6】:

        在 package.json 中添加"homepage": "http://mywebsite.com or IP/",

        更多信息:Building for Relative Paths

        【讨论】:

          猜你喜欢
          • 2014-11-25
          • 1970-01-01
          • 2019-04-22
          • 1970-01-01
          • 2021-08-18
          • 2018-08-21
          • 2018-08-07
          • 1970-01-01
          • 2017-01-03
          相关资源
          最近更新 更多