React-Router V4-无法获取* url *


74

我开始使用react-router v4。<Router>我的app.js中有一个简单的导航链接(请参见下面的代码)。如果我导航到localhost/vocabulary,路由器会将我重定向到正确的页面。但是,当我在之后按重新加载(F5)(localhost/vocabulary)时,所有内容消失并且浏览器报告Cannot GET /vocabulary。那怎么可能?有人可以给我任何解决方法的提示(正确重新加载页面)吗?

App.js:

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import { Switch, Redirect } from 'react-router'
import Login from './pages/Login'
import Vocabulary from './pages/Vocabulary'

const appContainer = document.getElementById('app')

ReactDOM.render(
  <Router>
    <div>
        <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/vocabulary">Vocabulary</Link></li>
        </ul>
        <Switch>
          <Route exact path="/" component={Login} />
          <Route exact path="/vocabulary" component={Vocabulary} />
        </Switch>
    </div>
  </Router>,
appContainer)

Answers:


219

我假设您正在使用Webpack。如果是这样,请在您的webpack配置中添加一些内容即可解决该问题。具体来说,output.publicPath = '/'devServer.historyApiFallback = true。这是下面的示例webpack配置,它同时使用^和为我解决刷新问题。如果您好奇“为什么”,会有所帮助。

var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './app/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index_bundle.js',
    publicPath: '/'
  },
  module: {
    rules: [
      { test: /\.(js)$/, use: 'babel-loader' },
      { test: /\.css$/, use: [ 'style-loader', 'css-loader' ]}
    ]
  },
  devServer: {
    historyApiFallback: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'app/index.html'
    })
  ]
};

我在这里写了更多关于此的内容-使用React Router(或客户端路由器的工作方式)修复刷新时无法获取“ / URL”错误


18
由添加的devServer工作:{historyApiFallback:true,}
SKLTFZ

并且不要将HtmlWebpackPlugin与index.html用作模板,因为在刷新路径时不会注入捆绑包。将bundle.js脚本直接作为脚本标签插入index.html中。
peterorum

4
它对我有用,只是添加了devServer { historyApiFallback: true } 我已经 publicPath: '/'配置的内容
Andre Evangelista

谢谢!在许多资料中,他们都说添加了historyApiFallback,但他们从未提及过output.publicPath ='/'。我没有配置我的publicPath,所以直到看到你的帖子我才能解决我的问题。
Nezih

1
向我+1,并且每次更改webpack.config.js时都不要忘记重新启动服务器(如果启用了热加载)。
BlondCode '18

15

只是为了补充泰勒对于仍在努力挣扎的人的回答:

将其添加devServer.historyApiFallback: true到我的webpack配置中(未设置publicPath),修复了在刷新/返回/转发时看到的404 / Cannot-GET错误,但仅适用于单个级别的嵌套路由。换句话说,“ /”和“ / topics”开始工作正常,但是超出此范围的任何内容(例如“ / topics / whatever”)仍在refresh / etc上抛出404。

刚刚在这里遇到了一个可以接受的答案:意外的令牌<反应路由器组件中的错误,它为我提供了最后一个缺少的部分。/在我的包脚本src中添加引导index.html已完全解决了该问题。


6

如果您的应用程序托管在静态文件服务器上,则需要使用而不是。

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

ReactDOM.render((
  <HashRouter>
    <App />
  </HashRouter>
), holder)

https://github.com/ReactTraining/react-router/blob/v4.1.1/FAQ.md#why-doesnt-my-application-render-after-refreshing


1
您引用的文章非常有帮助,因为我正在使用express.js。这篇文章中的代码为我提供了一个提示和解决方案,可以接受除“ /”之外的其他URL,因为它具有一个星号作为get()函数的参数。app.get('*',(req,res)=> {res.sendFile(path.resolve(__ dirname,'index.html'))})
Jerameel Resco

6

它对我有用devServer { historyApiFallback: true },只需要添加就可以,不需要使用publicPath: '/'

用法如下:

  devServer: {
    historyApiFallback: true
  },

3

我遇到了同样的问题,为我解决的问题是编辑package.json文件,scripts: {

"build": "webpack -d && copy src\\index.html dist\\index.html /y && webpack-dev-server --content-base src --inline --port 3000"

在我的webpackbuild代码末尾,我添加了--history-api-fallback 这似乎是解决该Cannot GET /url错误的最简单方法

注意:下一次在添加后进行构建时,--history-api-fallback您会注意到输出中的一行看起来像这样(无论您的索引文件是什么):

404将回退到/index.html


2

如果您使用的是Express(不是Webpack),那么这对我有用。

app.get('/*', function(req, res) {
  res.sendFile(path.join(__dirname, 'path/to/your/index.html'), function(err) {
    if (err) {
      res.status(500).send(err)
    }
  })
})

1

如果使用Webpack,请在服务器配置的一部分中检查“ contentBase”属性的配置。您可以通过以下示例进行设置:

devServer: {
    ...
    contentBase: path.join(__dirname, '../')
    ...
}

1

通过添加...我也成功完成了... historyApiFallback: true

devServer: {
    contentBase: path.join(__dirname, "public"),
    watchContentBase: true,
    publicPath: "/dist/",
    historyApiFallback: true
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.