【问题标题】:React-router v4 - cannot GET *url*React-router v4 - 无法获取 *url*
【发布时间】:2017-08-29 19:08:24
【问题描述】:

我开始使用 react-router v4。我的 app.js 中有一个简单的 <Router> 和一些导航链接(参见下面的代码)。如果我导航到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)

【问题讨论】:

标签: javascript reactjs routes localhost react-router


【解决方案1】:

我假设您正在使用 Webpack。如果是这样,在你的 webpack 配置中添加一些东西应该可以解决这个问题。具体来说,output.publicPath = '/'devServer.historyApiFallback = true。这是下面的示例 webpack 配置,它同时使用了 ^ 并为我修复了刷新问题。如果您对“为什么”感到好奇,this 会有所帮助。

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'
    })
  ]
};

我在这里写了更多关于这个 - Fixing the "cannot GET /URL" error on refresh with React Router (or how client side routers work)

【讨论】:

  • 由添加的 devServer 工作:{ historyApiFallback: true, },
  • 并且不要使用带有 index.html 的 HtmlWebpackPlugin 作为模板,因为在路由刷新时不会注入包。将 bundle.js 脚本直接作为脚本标签插入 index.html 中。
  • 添加devServer { historyApiFallback: true } 我已经配置了publicPath: '/' 对我有用
  • +1 来自我,并且每次更改 webpack.config.js 时不要忘记重新启动服务器(如果您启用了热加载)。
  • 它适用于 devServer。但是在构建之后它不起作用:(
【解决方案2】:

只是为了补充 Tyler 对仍在为此苦苦挣扎的人的回答:

devServer.historyApiFallback: true 添加到我的 webpack 配置(不设置 publicPath)修复了我在刷新/后退/前进时看到的 404/Cannot-GET 错误,但仅适用于单级嵌套路由。换句话说,“/”和“/topics”开始正常工作,但除此之外的任何内容(例如“/topics/whatever”)仍然在刷新/等时抛出 404。

刚刚在这里找到了公认的答案:Unexpected token < error in react router component,它为我提供了最后一个缺失的部分。将前导 / 添加到我的 index.html 中的捆绑脚本 src 已经完全解决了这个问题。

【讨论】:

    【解决方案3】:

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

    用法如下:

      devServer: {
        historyApiFallback: true
      },
    

    【讨论】:

      【解决方案4】:

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

      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

      【讨论】:

      • 你引用的文章真的很有帮助,因为我使用的是 express.js。这篇文章中的代码为我提供了接受除“/”之外的不同 URL 的提示和解决方案,因为它有一个星号作为 get() 函数的参数。 app.get('*', (req, res) => { res.sendFile(path.resolve(__dirname, 'index.html')) })
      【解决方案5】:

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

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

      在我的 webpack 末尾 build 代码我添加了 --history-api-fallback 这似乎也是Cannot GET /url 错误的最简单解决方案

      注意:在添加 --history-api-fallback 后下次构建时,您会注意到输出中的一行如下所示(无论您的索引文件是什么):

      404s 将回退到 /index.html

      【讨论】:

        【解决方案6】:

        如果你使用 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)
            }
          })
        })
        

        【讨论】:

        • 这段代码在哪里写?在后端的哪个文件中?我有 app.js , index.js ,然后在控制器内部有不同的路由器。我正在使用 express.js。还有关于 index.html 的路径。我们在谈论哪条路?我在后端的根目录中有前端构建文件夹。
        【解决方案7】:

        我也通过添加... historyApiFallback: true

        取得了成功
        devServer: {
            contentBase: path.join(__dirname, "public"),
            watchContentBase: true,
            publicPath: "/dist/",
            historyApiFallback: true
        }
        

        【讨论】:

        • 我在哪里添加这个?
        【解决方案8】:

        如果您使用 Webpack,请在服务器配置的一部分中检查您的配置 “内容基础”属性。你可以通过这个例子来设置:

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

        【讨论】:

          【解决方案9】:

          除了已接受的答案之外,如果您正在使用 HtmlWebpackPlugin 并且仍然出现错误,请仔细检查 filename 属性。如果您要专门为生产设置filename,则需要添加一个条件来设置filename 条件WEBPACK_DEV_SERVER 变量。请看下面的例子:

          new HtmlWebpackPlugin({
             template: './src/index.html',
             filename: process.env.WEBPACK_DEV_SERVER ? 'index.html' : PROD_HTML_PATH,
          })
          

          【讨论】:

          • PROD_HTML_PATH 是什么?
          • 这是您想要用于生产的路径的任意变量名称。变量可以命名为 @7urkm3n
          猜你喜欢
          • 1970-01-01
          • 2018-02-28
          • 2018-08-20
          • 1970-01-01
          • 2018-02-15
          • 2021-02-27
          • 2018-11-03
          • 2017-09-10
          • 1970-01-01
          相关资源
          最近更新 更多