React-router“无法获取/ *”除了根网址

Posted

技术标签:

【中文标题】React-router“无法获取/ *”除了根网址【英文标题】:React-router "Cannot GET /*" except for root url 【发布时间】:2015-11-12 21:43:15 【问题描述】:

我愿意为我的应用程序使用 React-router,我首先尝试the example given in the doc,我在下面复制了它。现在,当我转到localhost:3000/ 时,我按预期看到了“App”,但每隔一个页面,例如localhost:3000/inbox,就会返回“Cannot GET /inbox”。我在这里错过了什么?

var About = React.createClass(
  render: function () 
    return <h2>About</h2>;
);

var Inbox = React.createClass(
  render: function () 
    return <h2>Inbox</h2>;
);

var App = React.createClass(
  render () 
    return (
      <div><h1>App</h1>
        <RouteHandler/>
      </div>
));

var routes = (
  <Route path='/' handler=App>
    <Route path="about" handler=About/>
    <Route path="inbox" handler=Inbox/>
  </Route>
);

【问题讨论】:

【参考方案1】:

如果您使用的是webpack-dev-server,则有一个名为history-api-fallback 的选项。如果设置为true 404s 将回退到/index.html

将选项添加到 Webpack 配置的 devServer 部分,如下所示:

devServer: 
    contentBase: 'app/ui/www',
    devtool: 'eval',
    hot: true,
    inline: true,
    port: 3000,
    outputPath: buildPath,
    historyApiFallback: true,
,

Webpack 文档链接:https://webpack.github.io/docs/webpack-dev-server.html

【讨论】:

这应该是经过验证的答案!非常感谢! 这是问题的正确解决方案 谢谢,这就是答案!【参考方案2】:

我认为问题在于您正在发出 http 资源请求:

GET /inbox HTTP/1.1
Host: localhost:3000

但只使用客户端路由。您是否也打算进行服务器端渲染?您可能需要将路由器位置更改为 HistoryLocation 而不是 HashLocation(默认值)。

Router.run 的 location 属性告诉它匹配路由的位置。如果您没有运行服务器端 React,我相信您必须使用 Router.HashLocation(或将其留空)。

如果不是,您正在以错误的方式访问您的组件。尝试使用http://localhost:3000/#/inbox。熟悉 React-Router 可能需要一点时间,但绝对值得!

React Router Documentation - HashLocation

【讨论】:

感谢您的回答。我打电话给Router.run(routes, Router.HistoryLocation, function (Handler, state) ...,我不知道HashLocation。我所需要的只是根据我在“/”后添加的名称(例如,“/inbox”)显示不同的文本。 /#/ 返回相同的东西,无论我放在它后面(即,'/#/inbox' 被视为与 '/' 相同并显示 'App':state.params 是一个空对象)。 你在服务器上运行 React 吗?或者你只是在一个基本的 index.html 文件上安装 React? 我有一个 Apache 实例在 localhost:3000 为我的前端提供服务,并且那里的 index.html 包含 React.js 代码。如果有任何意义。我还有一个 Python 后端服务于 :8000,但我想它是不相关的。 所以基本上,当您点击 /index 时,Apache 服务器正在寻找另一个资源来启动,而不是保留在 index.html 文件中。您需要将 router.Run 更改为使用 Router.HashLocation,然后点击 /#/inbox(提供相同的 index.html 文档)。 这在 v2.x 中已经过时了。尝试在此处允许:github.com/reactjs/react-router/blob/master/docs/guides/…【参考方案3】:

最简单的选择:改用哈希历史。 url 不是很好,如果你需要更好的 SEO,我也会选择服务器端渲染。

如果您对此感兴趣,这个答案对我真的很有帮助:React-router urls don't work when refreshing or writting manually

【讨论】:

【参考方案4】:

请求将被发送到服务器,并且目录/文件并不真正存在,因此它将返回 404,因此您必须告诉服务器返回所有请求的索引页,并且 react 将处理 root :

如果您像我一样在 IIS 上托管您的 react 应用程序,只需添加一个包含以下内容的 web.config 文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" path="/" responseMode="ExecuteURL" />
    </httpErrors>
  </system.webServer>
</configuration>

这将告诉 IIS 服务器将主页返回给客户端,而不是 404 错误。

【讨论】:

【参考方案5】:

如果您有一个响应请求的服务器和一个 HashRouter(如果您使用的是静态文件服务器),我遇到了同样的问题。而不是使用 BrowserRouter 使用 HashRouter 它不是完美的修复,但应该解决 cannot GET "/path" 错误。确保从 'react-router-dom' 导入 HashRouter

render() 
    return (
        <div>
            <HashRouter>
                <Blog />
            </HashRouter>
        </div>
    );

来源:https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/guides/basic-components.md

【讨论】:

【参考方案6】:

添加到那些没有得到帮助的答案:historyApiFallback: true 仅适用于 url 的第一级。所以site.com/about 将被重定向到索引,但site.com/about/me 不会。在这种情况下,您需要添加rewrite 选项:

historyApiFallback: 
  rewrites: [
     from: /./, to: '/index.html' 
  ]

这将使用正则表达式匹配所有路由。注意还要添加这个:

  output: 
    // ...
    publicPath: '/'
    //...
  ,

否则,重定向将对 index.html 起作用,但 index.html 可能只有 bundle.js 作为 webpacked 脚本,并且无法正确读取。它应该是 '/bundle.js',此配置选项将执行此操作。

【讨论】:

以上是关于React-router“无法获取/ *”除了根网址的主要内容,如果未能解决你的问题,请参考以下文章

webpack-dev-server react-router 推送状态

React-router history.listen 没有在 componentWillMount 中运行

什么事云计算

React-Router面试题汇总

[react-router] React-Router 3和React-Router 4有什么变化?添加了什么好的特性?

[react-router] React-Router怎么获取历史对象?