React-router 2.0 browserHistory не работает при обновлении
Ниже приведены коды отчетов 404 при обновлении на странице http://localhost/about. Но если 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>
Я читал вопросы о неработающей версии browser-router v2.0 browserHistory, а URL-адреса React-router не работают при обновлении или записи вручную. Для первого я уже установил путь к абсолютному пути, но все еще не работает. Для второго я попытался импортировать экспресс, но не смог ("Uncaught TypeError: Невозможно прочитать свойство" prototype "из undefined").
4 ответа
Чтобы расширить ответ Фи Нгуена, причина, по которой hashHistory работает, а browserHistory не работает, заключается в том, что hashHistory - это своего рода "хак" или обходной путь, позволяющий вашему приложению манипулировать URL-адресом без уведомления и отправки браузером сообщения. GET
запрос на ваш сервер. По сути, все после хэша игнорируется.
browserHistory, как правило, предпочтительнее, потому что выглядит лучше, но вы больше не получаете обходной путь хеш-функции и вам нужны другие средства для предотвращения попытки браузера отправлять запросы на ваш сервер. Если вы используете webpack, существует простой способ сделать все запросы резервными для одного запроса. Например:
GET
на http://localhost:8080/ AND GET
на http://localhost:8080/about может произойти откат к http://localhost:8080/, а реагирующий маршрутизатор будет иметь дело с /about. (это причина, по которой вы можете переходить в / около штрафа, но если вы обновите, вы получите 404
ошибка, вы отправляете GET
к / о которой не существует на вашем сервере)
Для этого вам необходимо реализовать функцию веб-пакета, которая называется history api fallback. Есть два способа сделать это.
Из документации / руководства по реакторному маршрутизатору вы можете настроить start
Сценарий должен выглядеть так:
"start": "webpack-dev-server --inline --content-base . --history-api-fallback"
Где --history-api-fallback является важной частью для всех, у кого есть эта ошибка.
ИЛИ вы можете изменить свой webpack.config.js
файл, чтобы посмотреть обрабатывать это на вашем сервере разработки.
devServer: {
historyApiFallback: true,
...other stuff..
},
Альтернативный, простой и недорогой подход - заставить 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
Если вы используете netlify для развертывания своего сайта, вы можете создать файл _redirects в свой публичный каталог и добавить в него простую строку
/* /index.html 200
index.html - это просто файл, который вы используете в общей папке, как в этом примере
https://i.stack.imgur.com/tZXTa.png
_redirect файл
Когда вы используете browser history
сервер не знает, как обрабатывать URL, который изменяется только в браузере. Этот урок научит вас, как удалить #
в URL и сделать browser history
Работа.
Я получил работу с URL, добавив эту строку в блок сервера NGINX
try_files $uri $uri/ /index.html
Сервер дает вам 404, потому что / о не выходит. Вы должны принудительно обрабатывать каждый запрос через индексный файл вашей сборки, чтобы компонент Router мог подобрать в /about и правильно загрузить страницу.
Чтобы использовать browserHistory, вам нужно реализовать экспресс-сервер для обработки реальных URL-адресов. hashHistory не нуждается в экспресс-сервере.
Посмотрите на следующее руководство:
https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md