我正在使用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);
});

当前回答

如果你正在使用Create React App:

你可以在Create React App页面上找到许多主要托管平台的解决方案。例如,我使用React Router v4和Netlify作为前端代码。它只需要在我的公用文件夹中添加一个文件(“_redirects”),并在该文件中添加一行代码:

/*  /index.html  200

现在,当进入浏览器或有人点击刷新时,我的网站正确地呈现mysite.com/pricing这样的路径。

其他回答

当我在Electron中使用React作为前端,使用React -router-dom作为路由时,我就遇到了这个问题。

我用HashRouter替换了BrowserRouter,这是固定的。

这里有一个简单的例子:

import {
  HashRouter as Router,
  Switch,
  Route,
} from "react-router-dom";

如果你使用Apache作为你的web服务器,你可以在你的。htaccess文件中插入这个:

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

我正在使用react:“^16.12.0”和react-router:“^5.1.2” 这种方法是万能的,可能是最简单的入门方法。

因为我使用ASP。NET Core,类似这样的东西帮助了我:

public class HomeController : Controller
{
    public IActionResult Index()
    {
        var url = Request.Path + Request.QueryString;
        return App(url);
    }

    [Route("App")]
    public IActionResult App(string url)
    {
        return View("/wwwroot/app/build/index.html");
    }

}

基本上是在ASP上。NET MVC端,所有不匹配的路由都将落在startup.cs中指定的Home/Index中。在索引中,可以获取原始请求URL并将其传递到任何需要的地方。

文件startup.cs

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");

    routes.MapSpaFallbackRoute(
        name: "spa-fallback",
        defaults: new { controller = "Home", action = "Index" });
});

刷新DOM组件后无法得到403错误,这很简单。

只需在Webpack配置中添加这一行,'historyApiFallback: true '。这帮了我一整天的忙。

下面是我发现的一个前端解决方案,不需要修改服务器上的任何内容。

假设你的网站是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路由器渲染的组件)。