React-router URLs не работают при обновлении страницы или ручном вводе адреса
У меня проблема с использованием React-router. Все работает нормально, когда я нажимаю на кнопки-ссылки, но при обновлении страницы нужное мне содержимое не загружается.
Например, когда я нахожусь по адресу localhost/joblist
, все отлично, так как я попал на эту страницу, кликнув на ссылку. Но если я обновляю страницу, то получаю следующее сообщение об ошибке:
Cannot GET /joblist
Ранее по умолчанию у меня был такой URL: localhost/#/
и localhost/#/joblist
, и они работали исправно. Однако мне не нравятся такие URL, поэтому я решил убрать символ #
и написал следующий код:
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
Проблема не возникает с адресом localhost/
, этот адрес всегда возвращает нужное содержимое.
Мое приложение является одностраничным, поэтому /joblist
не должно запрашивать данные у сервера.
Вот весь мой роутер:
var routes = (
<Route name="app" path="/" handler={App}>
<Route name="joblist" path="/joblist" handler={JobList}/>
<DefaultRoute handler={Dashboard}/>
<NotFoundRoute handler={NotFound}/>
</Route>
);
Router.run(routes, Router.HistoryLocation, function (Handler) {
React.render(<Handler/>, document.body);
});
Мне нужно решение этой проблемы, чтобы при обновлении страницы содержимое по адресу /joblist
загружалось корректно.
5 ответ(ов)
Если вы используете Apache в качестве веб-сервера, вы можете вставить следующий код в ваш файл .htaccess
:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]
</IfModule>
Я использую react: "^16.12.0"
и react-router: "^5.1.2"
. Этот метод является универсальным и, вероятно, самым простым способом для начала.
Это может решить вашу проблему.
Я также столкнулся с аналогичной проблемой в приложении на React в режиме Production. Вот два решения, которые могут помочь.
Решение 1. Измените историю маршрутизации на "hashHistory" вместо "browserHistory" как показано ниже:
<Router history={hashHistory}>
<Route path="/home" component={Home} />
<Route path="/aboutus" component={AboutUs} />
</Router>
Теперь соберите приложение с помощью команды:
sudo npm run build
Затем разместите папку build в вашей директории var/www/. Теперь приложение будет работать корректно с добавлением символа # в каждый URL, например:
localhost/#/home
localhost/#/aboutus
Решение 2: Без использования символа #, с использованием browserHistory.
Установите history = в вашем маршрутизаторе. Затем снова соберите приложение с помощью sudo npm run build
.
Вам нужно создать конфигурационный файл для решения проблемы с 404 ошибкой. Конфигурационный файл должен выглядеть следующим образом.
Откройте терминал и введите следующие команды:
cd /etc/apache2/sites-available
ls
nano sample.conf
Добавьте в него следующее содержимое:
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName 0.0.0.0
ServerAlias 0.0.0.0
DocumentRoot /var/www/html/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/var/www/html/">
Options Indexes FollowSymLinks
AllowOverride all
Require all granted
</Directory>
</VirtualHost>
Теперь вам нужно активировать файл sample.conf, выполнив следующую команду:
cd /etc/apache2/sites-available
sudo a2ensite sample.conf
После этого вам будет предложено перезагрузить сервер Apache. Используйте команду:
sudo service apache2 reload или restart
Затем откройте папку localhost/build и добавьте файл .htaccess с следующим содержимым:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^.*$ / [L,QSA]
Теперь приложение должно работать нормально.
Примечание: Замените IP-адрес 0.0.0.0 на ваш локальный IP-адрес.
Чтобы решить вашу проблему, добавьте следующий код в файл webpack.config.js
:
devServer: {
historyApiFallback: true
}
Это позволит вашему приложению корректно обрабатывать маршрутизацию при использовании HTML5 History API. Теперь, если вы попытаетесь обратиться к URL, который не существует на сервере, devServer будет автоматически перенаправлять запрос на index.html
.
Если у вас есть запасной вариант для вашего index.html, убедитесь, что в вашем файле index.html присутствует следующий код:
<script>
System.config({ baseURL: '/' });
</script>
Обратите внимание, что это может различаться в зависимости от проекта.
Использование HashRouter
также сработало для меня вместе с Redux. Просто замените следующий код:
import {
Router // замените Router
} from "react-router-dom";
ReactDOM.render(
<LocaleProvider locale={enUS}>
<Provider store={Store}>
<Router history={history}> // замените здесь Router
<Layout/>
</Router>
</Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();
на этот:
import {
HashRouter // заменено на HashRouter
} from "react-router-dom";
ReactDOM.render(
<LocaleProvider locale={enUS}>
<Provider store={Store}>
<HashRouter history={history}> // заменено на HashRouter
<Layout/>
</HashRouter>
</Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();
Это должно помочь вам использовать маршрутизацию с Redux!
Как программно выполнять навигацию с помощью React Router?
Получение значений из параметров "GET" (JavaScript)
Как условно добавлять атрибуты к компонентам React?
Как установить фокус на поле ввода после рендеринга?
В чем разница между React Native и React?