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

当前回答

因为我使用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" });
});

其他回答

使用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();

我正在使用Webpack,也遇到了同样的问题。

解决方案:

在你的server.js文件中:

const express = require('express');
const app = express();

app.use(express.static(path.resolve(__dirname, '../dist')));
  app.get('*', function (req, res) {
    res.sendFile(path.resolve(__dirname, '../dist/index.html'));
    // res.end();
  });

为什么我的应用程序刷新后不呈现?

如果你正在使用Firebase,你所要做的就是确保你的Firebase中有一个重写属性。Json文件在你的应用程序的根(在托管部分)。

例如:

{
  "hosting": {
    "rewrites": [{
      "source":"**",
      "destination": "/index.html"
    }]
  }
}

有关此主题的进一步阅读:

配置重写 Firebase CLI:“配置为单页应用程序(重写所有url到/index.html)”

如果你使用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” 这种方法是万能的,可能是最简单的入门方法。

路由器可以用两种不同的方式调用,这取决于导航是发生在客户端还是服务器上。您已经将其配置为客户端操作。关键参数是run方法的第二个参数,即location。

当你使用React Router Link组件时,它会阻塞浏览器导航并调用transitionTo来做客户端导航。您正在使用HistoryLocation,因此它使用HTML5历史API通过在地址栏中模拟新URL来完成导航的错觉。如果您使用的是较旧的浏览器,这将不起作用。您将需要使用HashLocation组件。

When you hit refresh, you bypass all of the React and React Router code. The server gets the request for /joblist and it must return something. On the server you need to pass the path that was requested to the run method in order for it to render the correct view. You can use the same route map, but you'll probably need a different call to Router.run. As Charles points out, you can use URL rewriting to handle this. Another option is to use a Node.js server to handle all requests and pass the path value as the location argument.

例如,在Express.js中,它看起来是这样的:

var app = express();

app.get('*', function (req, res) { // This wildcard method handles all requests

    Router.run(routes, req.path, function (Handler, state) {
        var element = React.createElement(Handler);
        var html = React.renderToString(element);
        res.render('main', { content: html });
    });
});

请注意,正在传递请求路径以运行。为此,需要有一个服务器端视图引擎,可以将呈现的HTML传递给该引擎。在使用renderToString和在服务器上运行React时,还有许多其他注意事项。一旦页面在服务器上呈现,当你的应用程序在客户端加载时,它将再次呈现,并根据需要更新服务器端呈现的HTML。