Я работаю над веб-приложением create-реагировать-приложение (v2.1.8 на момент написания, поставляется с реакцией-router-dom v4.3.1), и мне нужна помощь, чтобы понять, почему оно работает так, как работает.
Моя первоначальная проблема связана с приложением, обслуживаемым AWS S3, и решается с помощью вопросов SO Реактивный маршрутизатор не работает в корзине aws s3 и URL-адреса React-маршрутизатора не работают при обновлении или записи вручную :
- Мой браузер получил 404s в моем приложении при попытке получить маршруты на стороне сервера. Это было решено путем указания S3
error.html
на index.html
...
- ... но это решило проблему только наполовину, так как запрос
/whatever/subresource
к S3 действительно вернет index.html
(спасибо 1. выше), но заставит S3 вернуть 403. Мое приложение находится за CloudFlare , Я работал вокруг после взлома CloudFlare Переопределить код состояния ответа от 404 до 200 для S3 SPA ?. В основном работник CloudFlare перехватывает запросы, и, если запрошенный URL-адрес соответствует CRA_APP_ROUTES = ['/route-a', '/route-b', '...']
, я возвращаю ответ (который равен index.html
из-за конфигурации S3, описанной в 1.), но с ответом 200
.
Вот мой вопрос:
- Я понял, что CRA использует React Router
browserHistory
(который за кулисами использует HTML5 pushState
history API ) для получения привлекательных URL-адресов в одностраничном приложении без #/...
.
- Я получаю, что
pushState
API истории будет изменять историю / URL без какой-либо навигации. Как задокументировано MDN / Добавление и изменение истории ,
Предположим, http://mozilla.org/foo.html
выполняет следующий JavaScript:
var stateObj = { foo: "bar" };
history.pushState(stateObj, "page 2", "bar.html");
Это приведет к отображению на строке URL http://mozilla.org/bar.html
, но не заставит браузер загрузить bar.html
или даже не проверить, существует ли bar.html
.
- И я получаю, что приложение «работает», когда обслуживается правильно настроенной экспресс-службой
index.html
для любых неизвестных путей. Как задокументировано Обслуживание приложений с маршрутизацией на стороне клиента ,
Сервер должен быть настроен для ответа на запрос /todos/42
, обслуживая index.html
. Например, мы можем изменить наш приведенный выше пример Express, чтобы он служил index.html
для любых неизвестных путей:
app.use(express.static(path.join(__dirname, 'build')));
-app.get('/', function (req, res) {
+app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
- Я понимаю, что все работает, потому что React Router распознает маршрут, по которому он идет, и соответствующим образом отображает.
Но , почему вообще делает сетевой запрос вообще? Зачем получать ресурсы, которые все попадают в index.html
и связанные JS, которые уже есть в моем браузере ?! Может ли CRA быть настроен на A. получить хорошую browserHistory
маршрутизацию и B. полностью на стороне клиента и не делать сетевых запросов при выполнении маршрутизации и повторной визуализации на стороне клиента ? (Это расточительно, поскольку S3 не выполняет рендеринг на стороне сервера и возвращает данные, которые уже есть у клиента). Я что-то упустил?
Спасибо.