#javascript #html #angular #service-worker #http-status-code-503
#javascript #HTML #angular #сервис-работник #http-status-code-503
Вопрос:
У меня есть веб-приложение Angular 8, которое использует Angular PWA и service worker.
Заказчик хочет добавить в систему режим обслуживания, чтобы иметь возможность отключать пользователей и отображать простую HTML-страницу с информацией о времени простоя.
На стороне сервера это работает просто путем возврата 503 и HTML-страницы в режиме обслуживания. Хотя страница основана на шаблоне, я не могу включить его в свое веб-приложение SPA, потому что администраторы клиента могут захотеть скорректировать его с учетом ситуации (например, чтобы объяснить, как долго будет продолжаться обслуживание).
Вопрос сводится к следующему: как заставить веб-браузер отображать удаленный index.html с текстом обслуживания вместо кэшированного index.html ? Как это обычно выполняется в типичном приложении Angular SPA, созданном с использованием шаблона Visual Studio Angular SPA?
Чем длиннее объяснения:
Проблема заключается в стороне клиента. Поскольку это PWA, который в основном взаимодействует с серверной частью через API, есть три потенциальных момента, когда пользователь может получить ответ 503:
-
при загрузке сайта в самый первый раз. Это не проблема, пользователи сразу получают страницу обслуживания.
-
когда сайт уже загружен и пользователь выполняет обычное обновление страницы (не полную перезагрузку). Это проблема, потому что кэшированный корень SPA index.html возвращается service worker вместо измененного index.html на сервере. К счастью, мой SPA выполняет некоторые веб-запросы сразу после запуска, поэтому я могу перехватить там 503, и, таким образом, все сводится к третьему пункту:
-
чаще всего статус 503 будет перехвачен, когда пользователь работает над какой-либо задачей, и приложение вызывает API моего сервера. У меня есть глобальный обработчик ошибок (основанный на ErrorHandler), добавленный к моим вызовам HTTP-службы в моем коде Angular, поэтому я могу перехватить ответ 503. Но что мне делать дальше? Как мне принудительно выполнить полную перезагрузку веб-сайта, игнорируя кэш service worker для принудительной перезагрузки удаленного index.html страница?
Что я уже пытался:
В качестве быстрого и грязного решения я добавил следующий код в свой обработчик ошибок:
if (error.status === 503) {
// the server should have offline page. If not, the request will lead to 404.
document.location.href = "offline.html?_=" Math.floor(Math.random() * 1000000000);
}
Это предполагает, что удаленный сервер имеет offline.html файл вместо недавно измененного index.html .
Проблема с этим подходом заключается в том, что пользователь не сможет просто продолжить обновление страницы, потому что они получат offline.html и, наконец, 404 вместо восстановленного index.html после восстановления сервера из режима обслуживания. Было бы лучше принудительно ввести текст обслуживания в том же index.html но, к сожалению, браузер продолжает отображать кэшированный SPA index.html вместо этого.
Ответ №1:
На случай, если кто-то другой наткнется на тот же вопрос: в итоге я получил такое немного уродливое решение:
else if (error.status === 503) {
// we assume the server has sent us entire offline html page contents
// and we rewrite current page with it entirely
document.open();
// error is the response body
document.write(error.error);
document.close();
}
Таким образом:
- если пользователь загружает веб-сайт в первый раз, он немедленно получит ответ сервера 503
- если пользователь загрузит веб-сайт из кэша браузера, веб-сайт получит 503 через некоторое время, но, скорее всего, очень скоро из-за некоторых немедленных запросов API, и тогда мы подходим к последнему:
- если пользователь получает статус 503 при вызове API, весь видимый документ будет заменен текстом с сервера.