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

Posted

技术标签:

【中文标题】React-router 2.0 browserHistory 刷新时不起作用【英文标题】:React-router 2.0 browserHistory doesn't work when refreshing 【发布时间】:2016-08-19 19:44:18 【问题描述】:

在页面http://localhost/about 上刷新时未找到以下代码报告 404。但是如果把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 working 和React-router urls don't work when refreshing or writting manually 的问题。对于第一个,我已经将路径设置为绝对路径,但仍然无法正常工作。对于第二个,我尝试导入 express 但失败('Uncaught TypeError: Cannot read property 'prototype' of undefined')。

【问题讨论】:

你用的是快递吗? 我尝试导入 express 4,但报 'Uncaught TypeError: Cannot read property 'prototype' of undefined' 我不明白,你用快递处理你的路线吗? 不,不是现在。前几天试了,没成功,把相关代码删了。 使用浏览器历史记录你需要在你的后端实现 /about,你可以使用 express 来做到这一点: var express = require('express'); var app = express(); // 当对主页发出 GET 请求时响应“hello world” app.get('/', function(req, res) res.render('index.html'); ); app.get('/about', function(req, res) res.render('index.html'); ); 【参考方案1】:

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

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

GET 到 http://localhost:8080/ 和 GET 到 http://localhost:8080/about 都将回退到 http://localhost:8080/ 并且 react-router 将处理 /about。 (这就是您可以导航到 /about 的原因,但如果您刷新会收到 404 错误,您正在向 /about 发送 GET ,但您的服务器上不存在)

为此,您需要实现一个名为 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..
  ,

【讨论】:

它将与这些步骤完美配合,devServer: historyApiFallback: index:'./index.html' , 所以这是在 webpack 开发服务器上设置的,通常只用于开发。在生产中,您是否仍需要在托管您的代码的任何服务器上进行配置? "您需要其他方法来阻止浏览器尝试向您的服务器发送请求" 对吗?我认为浏览器在刷新时会发送请求。这不是关于阻止,而是关于在服务器端处理请求。【参考方案2】:

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

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

# 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

【讨论】:

【参考方案3】:

当您使用browser history 时,服务器不知道如何处理仅在浏览器中更改的 URL。 这个tutorial会教你如何去掉url中的#,让browser history工作。

【讨论】:

【参考方案4】:

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

/*    /index.html   200

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

_重定向文件

【讨论】:

【参考方案5】:

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

查看以下指南:

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

【讨论】:

【参考方案6】:

通过将此行添加到 nginx 服务器块,我已经获得了 URL 工作原理

try_files $uri $uri/ /index.html

服务器给你一个 404 因为 /about 没有退出。您必须通过构建的索引文件强制每个请求,以便路由器组件可以在 /about 上获取并正确加载页面。

【讨论】:

以上是关于React-router 2.0 browserHistory 刷新时不起作用的主要内容,如果未能解决你的问题,请参考以下文章

react-router 4.0踩到的坑

react-router v2.0 的打字稿定义-错误`没有导出的成员'browserHistory'`

react-router 页面离开 url错误

browserHistory.push 没有导航到新页面

React-Router面试题汇总

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