我正在使用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做了一个网站,也遇到了同样的问题。

我使用react-router-dom包中的BrowserRouting。我在Nginx服务器上运行,添加以下到/etc/nginx/yourconfig.conf为我解决了这个问题:

location / {
  if (!-e $request_filename){
    rewrite ^(.*)$ /index.html break;
  }
}

如果你正在运行Apache,这对应于在.htaccess中添加以下内容:

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

这似乎也是Facebook自己提出的解决方案。

其他回答

在index.html文件头部,添加以下内容:

<base href="/">
<!-- This must come before the CSS and JavaScript code -->

然后,当与Webpack开发服务器一起运行时,使用此命令。

webpack-dev-server --mode development --hot --inline --content-base=dist --history-api-fallback

-history-api-fallback是重要的部分

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

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

这里有一个简单的例子:

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

对于React Router V4用户:

如果您试图通过其他答案中提到的哈希历史技术来解决这个问题,请注意

<Router history={hashHistory} >

在V4中不能工作。请改用HashRouter:

import { HashRouter } from 'react-router-dom'

<HashRouter>
  <App/>
</HashRouter>

参考:HashRouter

在后端使用Express.js,在前端使用React(没有React -create-app)和reach/router,正确的reach/router路由React组件会显示出来,当在地址栏中点击Enter时,菜单链接将被设置为活动样式,例如http://localhost:8050/pages。

请签出以下内容,或直接访问我的存储库https://github.com/nickjohngray/staticbackeditor。所有的代码都在那里。

网络包:

设置代理。这允许任何从端口3000 (React)调用服务器, 包括当按下回车键时在地址栏中获取index.html或任何东西的调用。它还允许调用API路由来获取JSON数据。

比如await axios。Post ('/api/login', {email, pwd}):

devServer: {
    port: 3000,
    open: true,
    proxy: {
      '/': 'http://localhost:8050',
    }
  }

设置Express.js路由

app.get('*', (req, res) => {
    console.log('sending index.html')
    res.sendFile(path.resolve('dist', 'index.html'))

});

这将匹配React的任何请求。它只返回dist文件夹中的index.html页面。当然,这个页面有一个更单页的React应用程序。(注意任何其他路由都应该出现在这个上面,在我的情况下,这些是我的API路由。)

反应路线

<Router>
    <Home path="/" />
    <Pages path="pages"/>
    <ErrorPage path="error"/>
    <Products path="products"/>
    <NotFound default />
</Router>

这些路由是在我的布局组件中定义的,当路径匹配时,该组件将加载相应的组件。

React布局构造函数

constructor(props) {
    super(props);

    this.props.changeURL({URL: globalHistory.location.pathname});
}

Layout构造函数在加载时立即被调用。在这里,我调用我的redux操作changeURL,我的菜单监听,所以它可以突出显示正确的菜单项,如下所示:

菜单的代码

<nav>
    {this.state.links.map( (link) =>
    <Link className={this.getActiveLinkClassName(link.path) } to={link.path}>
      {link.name}
    </Link>)}
</nav>

这里有一个简单、清晰和更好的解决方案。如果你使用网络服务器,它就可以工作。

每个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。

就是这样。不再需要魔法:)