Как я могу предотвратить загрузку кэшированной веб-страницы Chrome в автономном режиме? - PullRequest
7 голосов
/ 20 апреля 2020

Действия по воспроизведению проблемы:

  1. Пользователь заходит на веб-страницу, см. Код ниже.
  2. Пользователь закрывает Chrome.
  3. Устройство переходит в автономный режим (отключите все сети вручную).
  4. Пользователь повторно открывает браузер, находясь в полностью автономном режиме.
  5. Chrome автоматически отображает последнюю посещенную страницу, сохраненную копию веб-страницы. который говорит Online? true, даже после нажатия refre sh несколько раз.

Единственное, что говорит пользователю, что он / она смотрит на какую-то устаревшую, полностью непригодную копию веб-страницы, это это в адресной строке:

enter image description here

Нетехнические пользователи могут легко пропустить это, и они задаются вопросом, почему страница непригодна для использования ... Это плохой пользовательский опыт.

Браузер и устройство: Chrome 81 на Android 6 на Acer Iconia Tab 10 A3-40 планшет .

Веб-страница обслуживается через HTTPS (безопасное соединение).

Код:

const setMsg = (flag) => {
  const p = document.getElementById('msg')
  p.innerHTML = '<b>Online?</b>  ' + flag
}

setMsg(navigator.onLine)

window.addEventListener("online", () => {
  setMsg(true)
})
window.addEventListener("offline", () => {
  setMsg(false)
})
<p id='msg'> </p>

Насколько я могу сказать:

  • Chrome делает не повторный запуск any JavaScript на шаге 5, даже после нажатия refre sh.
  • Chrome не не также уважают Cache-Control: private, no-store; дважды проверил.

Пока что единственный способ предотвратить это - зарегистрировать работника службы. Когда у меня зарегистрирован сервисный работник, JavaScript перезапускается, и я могу правильно и четко сообщить пользователю, что он / она не в сети.

Без службы рабочий, как я могу запретить Chrome загружать устаревшую, непригодную для использования веб-страницу в автономном режиме?

Обычная страница "Нет inte rnet" с динозавром подходит, и это то, что я ожидал с Cache-Control: no-store.

1 Ответ

3 голосов
/ 25 апреля 2020

Очень не изящный обходной путь - использовать CSS анимацию, которая заставляет "автономный" элемент появляться сразу после заданного промежутка времени. С JavaScript вы можете непрерывно сбрасывать анимацию, предотвращая ее отображение, если только / 10 * * больше не запускается для ее сброса.

Для анимации в приведенном ниже примере установлено значение 3 секунды, и использует ключевые кадры, чтобы оставаться на opacity:0 до 99% продолжительности анимации, после чего она меняется на opacity:1.

В JavaScript мы можем сбрасывать анимацию каждые 1-2 секунды с помощью JavaScript удалив связанный с ним класс, принудительно перекомпоновав (например, извлекая offsetWidth ), а затем добавив обратно класс анимации.

В идеале на этих мобильных устройствах Chrome можно было бы вообще не кэшировать страницу. Различные заголовки, которые мы опробовали в комментариях к этому вопросу, не были учтены мобильным устройством без доступа к Inte rnet.

Отключение кэширования было бы более подходящим решением как по концепции, так и по исполнению. Имеющий интервал JavaScript, который постоянно вызывает переворачивание, не велик. Но он дает пользователю представление о том, что двигатель JavaScript прекратил работу, как и здесь.

В приведенном ниже примере кнопка «Simulate stop JS» просто очищает интервал, который продолжает сбрасывать загрузочную анимацию. Это только симуляция, но она имеет тот же эффект, что и JavaScript, который не запущен (проверено на изолированном сервере).

const overlay = document.getElementById('offline-overlay');

const stopJS =  document.getElementById('stopJS');

const heartbeat = () => {
  overlay.classList.remove("animate-overlay");
  void overlay.offsetWidth; 
  overlay.classList.add("animate-overlay");
}

const heartbeatInterval = setInterval( heartbeat, 1000);

stopJS.addEventListener("click", function(){
  clearInterval(heartbeatInterval);
});
@keyframes offline {
  0%   {opacity:0;}
  99%  {opacity:0;}
  100% {opacity:1;}
}

.animate-overlay{
  animation-name: offline;
  animation-duration: 3s;
}

#offline-overlay{
  background-color: rgba(255,255,255,.9);
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  display:flex;
  justify-content: center;
  align-items:center;
  pointer-events:none;
}

#offline-overlay span{
  font-size:300%;
  font-family: sans-serif;
  letter-spacing:5px;
  color: #888;
}
  <div id="offline-overlay" class="animate-overlay">
    <span>OFFLINE</span>
  </div>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam varius quam sed nulla feugiat varius. Praesent vitae mi et libero porttitor maximus. Suspendisse eu pulvinar quam. Phasellus id ante a elit faucibus cursus. Curabitur porttitor vehicula ornare. Suspendisse nec risus ex. Aenean bibendum auctor ex eget aliquet. Donec laoreet sem ut tortor viverra aliquam.</p>

<button id="stopJS">Simulate Stop JS</button>
...