我最近部署到 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;
由于 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>
在您的代码中:
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”。
您已成功修复它。我也有完全一样的问题。我不知道如何解决这个问题