我正在使用React-router,当我点击链接按钮时,它工作得很好,但当我刷新我的网页时,它没有加载我想要的东西。
例如,我在localhost/joblist和一切都很好,因为我到达这里按下一个链接。但如果我刷新网页,我会得到:
Cannot GET /joblist
默认情况下,它不是这样工作的。最初我有我的URL localhost/#/和localhost/#/joblist,他们工作得很好。但我不喜欢这种类型的URL,所以试图删除#,我写道:
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
这个问题不会发生在localhost/,这个总是返回我想要的。
这个应用程序是单页的,所以/joblist不需要向任何服务器询问任何事情。
我的整个路由器。
var routes = (
<Route name="app" path="/" handler={App}>
<Route name="joblist" path="/joblist" handler={JobList}/>
<DefaultRoute handler={Dashboard}/>
<NotFoundRoute handler={NotFound}/>
</Route>
);
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
下面是我发现的一个前端解决方案,不需要修改服务器上的任何内容。
假设你的网站是mysite.com,你有一个到mysite.com/about的React Route。
在index.js中,你可以挂载你的顶级组件,你可以像这样放另一个Router:
ReactDOM.render(
<Router>
<div>
<Route exact path="/" component={Home} />
<Route exact path="/about"
render={(props) => <Home {...props} refreshRout={"/about"}/>}
/>
</div>
</Router>,
我假设原始路由器位于虚拟DOM的顶级组件之下。如果你正在使用Django,你还必须在你的。url中捕获url:
urlpatterns = [
path('about/', views.index),
]
不过,这将取决于您使用的后端。请求mysite/about会让你进入index.js(在那里你挂载顶级组件),在那里你可以使用Route的渲染道具,而不是组件道具,并将'/about'作为道具传递给Home组件,在这个例子中。
在Home中,在componentDidMount()或useEffect()钩子中,执行以下操作:
useEffect() {
//check that this.props.refreshRoute actually exists before executing the
//following line
this.props.history.replace(this.props.refreshRoute);
}
我假设你的Home组件是这样渲染的:
<Router>
<Route exact path="/" component={SomeComponent} />
<Route path="/about" component={AboutComponent} />
</Router>
关于如何在路由中向组件传递道具,请参考(将道具传递给React路由器渲染的组件)。
为乔舒亚·戴克的答案添加更多信息。
如果你正在使用Firebase,并且想同时使用根路由和子目录路由,你需要在你的Firebase .json中添加以下代码:
{
"hosting": {
"rewrites": [
{
"source": "*",
"destination": "/index.html"
},
{
"source": "/subdirectory/**",
"destination": "/subdirectory/index.html"
}
]
}
}
例子:
你正在为客户建立一个网站。您希望网站的所有者在https://your.domain.com/management中添加信息,而网站的用户将导航到https://your.domain.com。
在这种情况下,您的火源。Json文件是这样的:
{
"hosting": {
"rewrites": [
{
"source": "*",
"destination": "/index.html"
},
{
"source": "/management/**",
"destination": "/management/index.html"
}
]
}
}
使用HashRouter对我来说也适用于Redux。只需简单地替换:
import {
Router //replace Router
} from "react-router-dom";
ReactDOM.render(
<LocaleProvider locale={enUS}>
<Provider store={Store}>
<Router history={history}> // Replace here saying Router
<Layout/>
</Router>
</Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();
:
import {
HashRouter // Replaced with HashRouter
} from "react-router-dom";
ReactDOM.render(
<LocaleProvider locale={enUS}>
<Provider store={Store}>
<HashRouter history={history}> //replaced with HashRouter
<Layout/>
</HashRouter>
</Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();
这可以解决你的问题。
在生产模式下的React应用程序中,我也遇到了同样的问题。这里有两个解决这个问题的方法。
解决方案1。将路由历史更改为“hashHistory”,而不是browserHistory
<Router history={hashHistory} >
<Route path="/home" component={Home} />
<Route path="/aboutus" component={AboutUs} />
</Router>
现在使用命令构建应用程序
sudo npm run build
然后将构建文件夹放在var/www/文件夹中。现在,在每个URL中添加#标签,应用程序就可以正常工作了。就像
localhost/#/home
localhost/#/aboutus
解决方案2:没有#标签使用browserHistory,
在路由器中设置你的history = {browserHistory}。现在使用sudo npm run build构建它。
您需要创建“conf”文件来解决404 not found页面。conf文件应该是这样的。
打开终端,输入以下命令
cd /etc/apache2/sites-available
ls
nano sample.conf
在其中添加以下内容
<VirtualHost *:80>
ServerAdmin admin@0.0.0.0
ServerName 0.0.0.0
ServerAlias 0.0.0.0
DocumentRoot /var/www/html/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/var/www/html/">
Options Indexes FollowSymLinks
AllowOverride all
Require all granted
</Directory>
</VirtualHost>
现在您需要使用以下命令启用sample.conf文件:
cd /etc/apache2/sites-available
sudo a2ensite sample.conf
然后,它将要求您重新加载Apache服务器,使用
sudo service apache2 reload or restart
然后打开您的localhost/build文件夹,并添加包含以下内容的.htaccess文件。
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^.*$ / [L,QSA]
现在应用程序运行正常。
注意:0.0.0.0 IP地址修改为本地IP地址。
这里有一个简单、清晰和更好的解决方案。如果你使用网络服务器,它就可以工作。
每个web服务器都有能力在出现HTTP 404时将用户重定向到错误页面。要解决此问题,需要将用户重定向到索引页。
如果您使用Java基础服务器(Tomcat或任何Java应用程序服务器),解决方案可能如下:
web . xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- WELCOME FILE LIST -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- ERROR PAGES DEFINITION -->
<error-page>
<error-code>404</error-code>
<location>/index.jsp</location>
</error-page>
</web-app>
例子:
得到http://example.com/about
web服务器抛出HTTP 404,因为此页面在服务器端不存在
错误页面配置通知服务器将index.jsp页面发送回用户
那么JavaScript将在客户端完成剩下的工作,因为客户端的URL仍然是http://example.com/about。
就是这样。不再需要魔法:)