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

jchrr9hc  于 2023-08-06  发布在  React
关注(0)|答案(2)|浏览(102)

我最近部署到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中的homepage字段设置为我的应用的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;

3ks5zfa0

3ks5zfa01#

由于React App是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>

字符串

s6fujrry

s6fujrry2#

在代码中:

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组件中的basename,我的意思是-在App.js文件中,您正在使用react-router-dom中Router组件中的basename prop。由于您将应用托管在域的子目录中,因此请确保正确设置了基本名称。例如,如果您的应用托管在https://quierotraspasarlo.com/app上,则基名应为“/app”。

相关问题