Глядя на комментарии к принятому ответу и общий характер этого вопроса («не работает»), я подумал, что это может быть хорошим местом для некоторых общих объяснений по вопросам, связанным с этим. Таким образом, этот ответ предназначен в качестве справочной информации / разработки по конкретному варианту использования ОП. Пожалуйста, потерпите меня.
Сторона сервера против стороны клиента
Первая важная вещь, которую нужно понять, это то, что теперь есть 2 места, где URL интерпретируется, тогда как раньше было «1» в «старые времена». В прошлом, когда жизнь была простой, какой-то пользователь отправлял запрос наhttp://example.com/about
сервер, который проверял часть пути URL-адреса, определял, что пользователь запрашивает страницу about, а затем отправлял эту страницу обратно.
С маршрутизацией на стороне клиента, которую предоставляет React-Router, все не так просто. Во-первых, у клиента еще нет загруженного кода JS. Так что самый первый запрос всегда будет на сервер. Затем будет возвращена страница, которая содержит необходимые теги сценариев для загрузки React, React Router и т. Д. Только после загрузки этих сценариев начинается фаза 2. В фазе 2, когда пользователь нажимает на «О нас» ссылки навигации, например, URL - адрес изменяется только локально , чтобы http://example.com/about
( что стало возможным благодаря History API ), но никакого запроса на сервер не выполнен, Вместо этого React Router делает свое дело на стороне клиента, определяет, какое представление React отображать, и отображает его. Предполагая, что вашей странице about не нужно совершать какие-либо вызовы REST, это уже сделано. Вы перешли из дома в О нас без каких-либо запросов к серверу.
Таким образом, в основном, когда вы нажимаете на ссылку, запускается Javascript, который обрабатывает URL в адресной строке, не вызывая обновления страницы , что, в свою очередь, заставляет React Router выполнять переход страницы на стороне клиента .
Но теперь подумайте, что произойдет, если скопировать и вставить URL-адрес в адресную строку и отправить его другу по электронной почте. Ваш друг еще не загрузил ваш сайт. Другими словами, она все еще в фазе 1 . На ее компьютере еще не запущен React Router. Так что ее браузер сделает запрос к серверуhttp://example.com/about
.
И вот тут начинается твоя проблема. До сих пор вы могли бы просто разместить статический HTML-код в корне вашего сервера. Но это приведет к 404
ошибкам для всех других URL-адресов при запросе с сервера . Те же URL-адреса прекрасно работают на стороне клиента , потому что там React Router выполняет маршрутизацию за вас, но они терпят неудачу на стороне сервера, если вы не заставите свой сервер их понять.
Объединение серверной и клиентской маршрутизации
Если вы хотите, чтобы http://example.com/about
URL работал как на стороне сервера, так и на стороне клиента, вам необходимо настроить для него маршруты как на стороне сервера, так и на стороне клиента. Имеет смысл правильно?
И вот тут начинается ваш выбор. Решения варьируются от полного обхода проблемы через универсальный маршрут, который возвращает загрузочный HTML, до полного изоморфного подхода, когда и сервер, и клиент запускают один и тот же код JS.
,
Обход проблемы в целом: Hash History
Если вместо истории браузеров использовать историюhttp://example.com/#/about
хэшей , ваш URL-адрес страницы about будет выглядеть примерно так:
Часть после #
символа hash ( ) не отправляется на сервер. Таким образом, сервер только видит http://example.com/
и отправляет страницу индекса, как и ожидалось. React-Router подберет#/about
деталь и покажет правильную страницу.
Недостатки :
- "уродливые" URL
- При таком подходе рендеринг на стороне сервера невозможен. Что касается поисковой оптимизации (SEO), ваш сайт состоит из одной страницы, на которой почти нет контента.
,
Вместилище разнообразных предметов
При таком подходе вы используете историю браузера, а просто настроить улов-все на сервере , который посылает /*
к index.html
, фактически давая вам много такую же ситуацию , как с историей Hash. Тем не менее, у вас есть чистые URL-адреса, и вы могли бы улучшить эту схему позже, не делая недействительными все избранное вашего пользователя.
Недостатки :
- Более сложная настройка
- Все еще нет хорошего SEO
,
Гибридный
В гибридном подходе вы расширяете общий сценарий, добавляя конкретные сценарии для определенных маршрутов. Вы можете сделать несколько простых сценариев PHP, чтобы вернуть наиболее важные страницы вашего сайта с включенным содержимым, чтобы робот Googlebot мог хотя бы увидеть, что находится на вашей странице.
Недостатки :
- Еще сложнее настроить
- Только хороший SEO для тех маршрутов, которые вы предоставляете специальную обработку
- Дублирование кода для рендеринга контента на сервере и клиенте
,
изоморфный
Что если мы используем Node JS в качестве нашего сервера, чтобы мы могли запускать один и тот же код JS на обоих концах? Теперь у нас есть все наши маршруты, определенные в одной конфигурации реакции-маршрутизатора, и нам не нужно дублировать наш код рендеринга. Это, так сказать, «Святой Грааль». Сервер отправляет ту же самую разметку, которую мы получили бы в случае перехода страницы на клиенте. Это решение является оптимальным с точки зрения SEO.
Недостатки :
- Сервер должен (быть в состоянии) запустить JS. Я экспериментировал с Java icw Nashorn, но он не работает для меня. На практике это в основном означает, что вы должны использовать сервер на базе Node JS.
- Многие сложные экологические проблемы (использование
window
на стороне сервера и т. Д.)
- Крутая кривая обучения
,
Какой я должен использовать?
Выберите тот, который вы можете сойти с рук. Лично я думаю, что все достаточно просто настроить, так что это мой минимум. Эта настройка позволяет вам улучшать вещи с течением времени. Если вы уже используете Node JS в качестве серверной платформы, я бы определенно занялся созданием изоморфного приложения. Да, сначала это сложно, но как только вы освоитесь, это действительно очень элегантное решение проблемы.
В общем, для меня это было бы решающим фактором. Если мой сервер работает на Node JS, я бы стал изоморфным; В противном случае я бы выбрал решение Catch-all и просто расширил его (Гибридное решение), когда время идет, а требования SEO требуют этого.
Если вы хотите больше узнать об изоморфном (также называемом «универсальным») рендеринге с помощью React, есть несколько хороших учебников по этому вопросу:
Кроме того, чтобы начать, я рекомендую взглянуть на некоторые стартовые наборы. Выберите тот, который соответствует вашему выбору для технологического стека (помните, React - это просто V в MVC, вам нужно больше вещей для создания полноценного приложения). Начните с просмотра того, что опубликовано самим Facebook:
Или выберите один из множества сообществ. Теперь есть хороший сайт, который пытается проиндексировать их все:
Я начал с этого:
В настоящее время я использую самодельную версию универсального рендеринга, которая была вдохновлена двумя вышеперечисленными стартовыми наборами, но сейчас они устарели.
Удачи в вашем квесте!