React-router 2.0 browserHistory 在刷新时不起作用

IT技术 reactjs react-router jsx
2021-03-31 02:10:06

在页面http://localhost/about上刷新时,以下代码报告 404 not found 但是如果将 browserHistory 更改为 hashHistory,它就可以正常工作。

这是我的 js 文件。

import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, IndexRoute, Link, IndexLink, browserHistory, hashHistory } from 'react-router';
import $ from 'jquery';

class App extends Component {
  render() {
    return (
      <div>
        <h1>APP!</h1>
        <Link to="/about">/about</Link>
        {this.props.children}
      </div>
    )
  }
}

class About extends React.Component {
  render() {
    return (
      <div>
        <h2>About 33</h2>
      </div>
    )
  }
}

var routes = (
    <Router history={hashHistory}>
        <Route path="/" component={App} />
        <Route path="/about" component={About} />
        <Route path="/wealth" component={WealthExpectation} />
    </Router>
)

$(document).ready(function() {ReactDOM.render(routes, document.getElementById("hello"))});

和 html 文件。

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Hello React</title>
        <script type="text/javascript" src="/static/js/jquery-1.12.2.min.js"></script>
        <script type="text/javascript" src="/static/js/script.js"></script>
        <!-- build:css -->
          <link rel="stylesheet" type="text/css" href="/static/bower_modules/c3/c3.min.css">
        <!-- endbuild -->
    </head>
    <body>
        <div id="hello">a</div>
        <div id="world"></div>
    </body>
</html>

我已经阅读了关于react-router v2.0 browserHistory not workingReact-router urls don't work when refresh or witting manual 的问题对于第一个,我已经将路径设置为绝对路径,但仍然无法正常工作。对于第二个,我尝试导入 express 但失败了('Uncaught TypeError: Cannot read property 'prototype' of undefined')。

6个回答

为了扩展 Phi Nguyen 的回答,hashHistory 有效而 browserHistory 失败的原因是因为 hashHistory 是一种“黑客”或变通方法,允许您的应用程序在浏览器不注意到GET并向您的服务器发送请求的情况下操纵 URL 基本上忽略哈希之后的所有内容。

browserHistory 通常是首选,因为它看起来更好,但您不再获得哈希解决方法,并且您需要其他方法来防止浏览器尝试向您的服务器发送请求。如果您正在使用 webpack,则有一种简单的方法可以使所有请求回退到单个请求。例如:

GEThttp://localhost:8080/GEThttp://localhost:8080/about都会回退到http://localhost:8080/并且 react-router 会处理 /about。(这就是你能够导航到 /about 的原因,但是如果你刷新你会得到一个404错误,你发送一个GET到 /about 你的服务器上不存在)

为此,您需要实现一个名为 history api fallback 的 webpack 功能。有两种方法可以做到这一点。

从 react-router 文档/教程中,您可以将start脚本设置为如下所示:

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

--history-api-fallback 对于任何有此错误的人来说都是重要的部分。

或者您可以更改您的webpack.config.js文件以在您的开发服务器上处理此问题。

  devServer: {
    historyApiFallback: true,
    ...other stuff..
  },
所以这是在 webpack 开发服务器上设置的,它通常只用于开发。在生产中,您是否仍然需要在托管代码的任何服务器上进行配置?
2021-05-24 02:10:06
它将完美地配合这些步骤, devServer: { historyApiFallback:{ index:'./index.html' },
2021-06-03 02:10:06
“您需要其他方法来阻止您的浏览器尝试向您的服务器发送请求”是这样吗?我认为浏览器在刷新时发送请求。这不是关于防止而是关于在服务器端处理请求。
2021-06-04 02:10:06

另一种简单且低成本的方法是让 Apache 将任何请求映射到您的 React 应用程序。例如:http://localhost/about内部通过http://localhost/[my-own-html-file.html]

例如,如果我们的 React 应用程序从 开始index.html,您需要.htaccess在您的 React 应用程序上创建一个文件并插入以下代码:

# Map all non-existing URLs to be processed by index.html,
# so any URL that doesn't point to a JS file, CSS file, etc etc...
# goes through my React app.

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^ index.html [L]
</IfModule>

顺便说一句,这个 HTACCESS 代码改编自 Drupal 8:https : //github.com/drupal/drupal/blob/8.2.x/.htaccess

当您使用 时browser history,服务器不知道如何处理仅在浏览器中更改的 URL。教程将教您如何#在 url 中删除并使其browser history工作。

如果您使用 netlify 来部署您的站点,您可以创建一个文件_redirects到您的公共目录并在其中添加一个简单的行

/*    /index.html   200

index.html 只是您在公用文件夹中使用的文件,例如本例

在此处输入图片说明

_重定向文件

在此处输入图片说明

为了使用 browserHistory,您需要实现一个快速服务器来处理真实的 URL。hashHistory 不需要快速服务器。

看看以下指南:

https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md