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

当前回答

如果你正在使用Apache并且没有。htaccess文件,这是一个适合我的配置文件:

sites-enabled/somedomain.com.conf

<VirtualHost *:80>
    ServerName somedomain.com
    ServerAlias *.somedomain.com
    DocumentRoot /www/somedomain.com/build

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /www/somedomain.com/build/index.html [L,NC,QSA]

</VirtualHost>

其他回答

我还没有使用服务器端渲染,但我遇到了与OP相同的问题,其中Link在大多数时候似乎工作正常,但当我有一个参数时就失败了。我将在这里记录我的解决方案,看看它是否对任何人都有帮助。

我的主要JSX内容包括:

<Route onEnter={requireLogin} path="detail/:id" component={ModelDetail} />

这对于第一个匹配的链接很有效,但是当嵌套在该模型的详细页面上的< link >表达式中的:id发生变化时,浏览器栏中的URL会发生变化,但页面的内容最初并没有改变以反映链接的模型。

问题是我已经使用props.params.id在componentDidMount中设置了模型。组件只挂载一次,因此这意味着第一个模型是粘贴在页面上的模型,随后的链接更改了道具,但保持页面看起来不变。

在componentDidMount和componentWillReceiveProps的组件状态中设置模型(其中它基于下一个道具)可以解决问题,并且页面内容更改以反映所需的模型。

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

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

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

如果您正在使用“create-react-app”命令,

生成一个React应用程序,然后生成包。json文件需要有一个更改,以在浏览器中正常运行的产品构建React SPA。打开文件包。Json,并添加以下代码段,

"start": "webpack-dev-server --inline --content-base . --history-api-fallback"

这里最重要的部分是“——history- API -fallback”,用于启用历史API回调。

如果使用Spring或任何其他后端API,有时会出现404错误。因此,在这种情况下,您需要在后端有一个控制器,将任何请求(您想要的)转发给index.html文件,由react-router处理。下面演示了一个使用Spring编写的示例控制器。

@Controller
public class ForwardingController {
    @RequestMapping("/<any end point name>/{path:[^\\.]+}/**")
    public String forward(HttpServletRequest httpServletRequest) {
        return "forward:/";
    }
}

例如,如果我们取一个后端API REST端点为“abc”(http://localhost:8080/abc/**),任何到达该端点的请求都将重定向到React应用程序(index.html文件),然后React -router将处理它。

为乔舒亚·戴克的答案添加更多信息。

如果你正在使用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"
      }
    ]
  }
}

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

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