React Router 在部署到托管服务器后无法正常工作

问题描述 投票:0回答:3

我最近部署到 Banahosting 的 React 应用程序遇到问题。该应用程序在本地环境中运行良好,当我点击网页内的链接时,页面会刷新;但是当使用托管服务器构建并上传到互联网时,导航会被破坏。问题是这样的:

当我导航到网站 (https://quierotraspasarlo.com) 时,主页加载正常,但是当我单击链接时,地址栏中的 URL 发生变化,但页面不会重新加载以反映新路线。但是,如果我在地址栏中手动输入新 URL 并刷新页面,它将加载正确的页面。

我使用react-router-dom进行路由。以下是我设置主 App.js 文件的方法:

import React, { createContext } from "react";
import { BrowserRouter  as Router } from "react-router-dom";
import "./App.css";
import TopBar from "./components/TopBar";
import MainContent from "./components/MainContent";
import Footer from "./components/Footer";

export const CurrencyContext = createContext();

const App = () => {
  const currency = "€";
  return (
    <CurrencyContext.Provider value={currency}>
      <Router basename={process.env.PUBLIC_URL}>
        <div className="app">
          <TopBar />
          <MainContent />
          <Footer></Footer>
        </div>
      </Router>
    </CurrencyContext.Provider>
  );
};

export default App;

我尝试过的事情:

我尝试使用

<HashRouter>
而不是
<BrowserRouter>
。这导致 URL 看起来像 https://quierotraspasarlo.com/#/city/2,但问题仍然存在。

我已在应用程序的公共目录中包含一个 .htaccess 文件,并遵循以下规则:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

我确保我的服务器上启用了 Apache

mod_rewrite
模块。

我尝试将 package.json 中的主页字段设置为我的应用程序的 URL(“homepage”:“https://quierotraspasarlo.com”)。 尽管做出了所有这些努力,问题仍然存在。任何关于我在这里可能缺少的内容的建议或指导将不胜感激。

提前感谢您的帮助!

PD:我知道这个问题有点具体,因为所有信息都与我的网页相关,但任何试图将其项目上传到“互联网”的人都可能会出现此问题,即使用 托管服务 来托管他们的项目网页(并且其导航在本地环境中效果很好)。

这是

MainContent.js
文件:

import React, { useState } from "react";
import { Routes, Route } from "react-router-dom";
import CityCarousel from "./CityCarousel";
import WelcomeBanner from "./WelcomeBanner";
import WhyQuieroTraspasarlo from "./WhyQuieroTraspasarlo";
import CityPage from "./CityPage";
import BusinessPage from "./BusinessPage";
import PrivacyPolicy from "./PrivacyPolicy";
import ConditionsOfUse from "./ConditionsOfUse";
import NotFoundPage from "./NotFoundPage";
import AllCitiesPage from "./AllCitiesPage";
import ImInterestedContactForm from "./ImInterestedContactForm";
import BusinessContext from "./BusinessContext";
import IHaveABusinessForm from "./IHaveABusinessForm";
import BusinessAdBanner from "./BusinessAdBanner";
import PopularBusinessesBanner from "./PopularBusinessesBanner";
import HowQuieroTraspasarloWorks from "./HowQuieroTraspasarloWorks";
import "./MainContent.css";

const FullHome = () => {
  return (
    <>
      <WelcomeBanner />
      <div className="break-0x2vw" />
      <CityCarousel />
      <div className="break-0x2vw" />
      <PopularBusinessesBanner />
      <div className="break-0x2vw" />
      <HowQuieroTraspasarloWorks />
      <div className="break-0x2vw" />
      <BusinessAdBanner />
      <div className="break-0x2vw" />

      <WhyQuieroTraspasarlo />
      <div className="break-0x2vw" />
    </>
  );
};

const MainContent = () => {
  const [businessData, setBusinessData] = useState({});

  return (
    <BusinessContext.Provider value={{ businessData, setBusinessData }}>
      <Routes>
        <Route path="/" element={<FullHome />} />
        <Route path="/city/:cityId" element={<CityPage />} />
        <Route
          path="/city/:cityId/business/:businessId"
          element={<BusinessPage setBusinessData={setBusinessData} />}
        />
        <Route path="/contact" element={<ImInterestedContactForm />} />
        <Route path="/all-cities" element={<AllCitiesPage />} />
        <Route path="/privacy-policy" element={<PrivacyPolicy />} />
        <Route path="/conditions-of-use" element={<ConditionsOfUse />} />
        <Route path="/publish-business" element={<IHaveABusinessForm />} />
        <Route path="*" element={<NotFoundPage />} />
      </Routes>
    </BusinessContext.Provider>
  );
};

export default MainContent;

apache .htaccess build hosting router
3个回答
0
投票

由于 React 应用程序是 SPA,因此服务器只知道一条路由,因为只有一个 HTML 文件 (

index.html
)。每次您请求不同路线的内容时,底层 JavaScript 都会替换该单个页面的内容,同时向浏览器导航历史记录添加一个新层。

您唯一要做的就是告诉服务器将任何路由请求重定向到主页(

/
),这正是这一行的作用:
RewriteRule . /index.html [L]
。我在使用 Apache 服务器 (000webhost.com) 时遇到了同样的问题,我可以使用我的
.htaccess
文件中的以下规则来解决它。

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l (Missing from your config)
  RewriteRule . /index.html [L]
</IfModule>

0
投票

在您的代码中:

import React, { createContext } from "react";
import { BrowserRouter as Router } from "react-router-dom";
import "./App.css";
import TopBar from "./components/TopBar";
import MainContent from "./components/MainContent";
import Footer from "./components/Footer";

export const CurrencyContext = createContext();

const App = () => {
  const currency = "€";
  return (
    <CurrencyContext.Provider value={currency}>
      <Router basename={process.env.PUBLIC_URL}>
        <div className="app">
          <TopBar />
          <MainContent />
          <Footer></Footer>
        </div>
      </Router>
    </CurrencyContext.Provider>
  );
};

export default App;

验证用于配置 Apache Web 服务器的 .htaccess 文件的配置是否正确。看来您已经包含了重写 URL 的必要规则,但请确保 .htaccess 文件位于应用程序的根目录中,与您的 index.html 文件一起。另外,请确认您的托管服务器上启用了 mod_rewrite

尝试检查 Router 组件中的基本名称,我的意思是 - 在 App.js 文件中,您正在使用来自 React-router-dom 的 Router 组件中的 basename 属性。由于您将应用程序托管在域的子目录中,因此请确保基本名称设置正确。例如,如果您的应用程序托管在 https://quierotraspasarlo.com/app,则基本名称应为“/app”。


0
投票

您已成功修复它。我也有完全一样的问题。我不知道如何解决这个问题

© www.soinside.com 2019 - 2024. All rights reserved.