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

当前回答

我喜欢这种处理方式。尝试添加: yourSPAPageRoute/*在服务器端消除这个问题。

我采用了这种方法,因为即使是原生HTML5 History API也不支持页面刷新时的正确重定向(据我所知)。

注意:选定的答案已经解决了这个问题,但我试图更具体。

表达的路线

其他回答

这里的答案都非常有用。配置我的Webpack服务器以期望路由对我有效。

devServer: {
   historyApiFallback: true,
   contentBase: './',
   hot: true
},

historyApiFallback为我修复了这个问题。现在路由工作正确,我可以刷新页面或直接输入URL。没有必要担心Node.js服务器上的变通方法。这个答案显然只适用于使用Webpack的情况。

查看我对React-router 2.0 browserHistory在刷新时不工作的回答,了解为什么需要刷新的更详细原因。

如果你正在使用nginx托管,需要快速修复…

在你的nginx配置中添加以下代码:

location / {
  try_files $uri /index.html;
}

修复在刷新或直接调用URL时“不能GET /URL”的错误。

配置你的webpack.config.js,以期望给定的链接像这样的路由。

module.exports = {
  entry: './app/index.js',
  output: {
       path: path.join(__dirname, '/bundle'),
       filename: 'index_bundle.js',
       publicPath: '/'
  },

用Laravel在React中实现JavaScript SPA的解决方案

公认的答案是对为什么会发生这样的问题的最好解释。如前所述,您必须同时配置客户端和服务器端。

在你的blade模板中,包括JavaScript绑定文件,确保像这样使用URL外观:

<script src="{{ URL::to('js/user/spa.js') }}"></script>

在路由中,确保将此添加到刀片模板所在的主端点。例如,

Route::get('/setting-alerts', function () {
   return view('user.set-alerts');
});

以上是刀片模板的主要端点。现在再添加一条可选路线,

Route::get('/setting-alerts/{spa?}', function () {
  return view('user.set-alerts');
});

发生的问题是,首先加载刀片模板,然后加载React路由器。当你加载'/setting-alerts'时,它会加载HTML内容和JavaScript代码。

但是当你加载'/setting-alerts/about'时,它首先在服务器端加载。因为它在服务器端,所以这个位置上没有任何东西,并且它返回not found。当你有可选的路由器时,它加载同一个页面,React路由器也被加载,然后React加载器决定显示哪个组件。

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