Книга: JavaScript. Подробное руководство, 6-е издание

20.4.2. Обновление кэша

20.4.2. Обновление кэша

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

CACHE MANIFEST
# МуАрр версия 1 (изменяйте этот номер, чтобы заставить броузеры повторно
# загрузить следующие файлы)
MyApp.html
МуАрр.js

Аналогично, если потребуется, чтобы веб-приложение удалило себя из кэша приложений, следует удалить файл объявления на сервере, чтобы на запрос этого файла возвращался бы НТТР-ответ 404 «Not Found», и изменить HTML-файл или файлы, удалив из них ссылки на файл объявления.

Обратите внимание, что броузеры проверяют файл объявления и обновляют кэш асинхронно, после (или во время) загрузки копии приложения из кэша. Для простых веб-приложений это означает, что после обновления файла объявления пользователь должен дважды загрузить приложение, чтобы получить обновленную версию: в первый раз будет загружена старая версия из кэша, после чего произойдет обновление файлов в кэше, а во второй раз из кэша будет загружена новая версия.

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

applicationCache.onupdateready = function() {
  var reload = confirm("Доступна новая версия приложения, котораяn” +
                     "будет использована при следующем запуске.n" +
                     "Хотите ли перезапустить ее сейчас?");
  if (reload) location.reload();
}

Обратите внимание, что этот обработчик событий регистрируется в объекте ApplicationCache, на который ссылается свойство applicationCache объекта Window. Броузеры, поддерживающие кэш приложений, определяют это свойство. Помимо события «updateready», показанного выше, существует еще семь различных событий, имеющих отношение к кэшу приложений. В примере 20.4 демонстрируются простые обработчики, которые выводят сообщения, информирующие пользователя о ходе обновления кэша и о его текущем состоянии.

Пример 20.4. Обработка событий кэша приложений

// Эту функцию используют все обработчики событий, реализованные ниже, и выводят
// с ее помощью сообщения, информирующие о состоянии кэша приложений.
// Поскольку все обработчики отображают сообщения таким способом, они
// возвращают false, чтобы отменить дальнейшее распространение события
// и предотвратить вывод сообщений самим броузером,
function status(msg) {
  // Вывести сообщение в элементе документа с
  document.getElementById("statusline").innerHTML = msg;
  console.log(msg); // А также в консоли для отладки
}
// Каждый раз, когда приложение загружается, броузер проверяет файл объявления.
// В начале этого процесса первым всегда генерируется событие "checking",
window.applicationCache.onchecking = function() {
  status("Проверка наличия новой версии.");
  return false;
};
// Если файл объявления не изменился и приложение уже имеется в кэше,
// генерируется событие "noupdate" и процедура проверки заканчивается,
window.applicationCache.onnoupdate = function() {
  status("Версия приложения не изменилась.")
  return false;
};
// Если приложение отсутствует в кэше или если изменился файл объявления,
// броузер загрузит и поместит в кэш все, что перечислено в файле объявления.
// Событие "downloading" свидетельствует о начале этой процедуры загрузки,
window.applicationCache.ondownloading = function() {
  status("Загружается новая версия");
  window.progresscount = 0; // Используется в обработчике "progress" ниже
  return false;
};
// В ходе загрузки периодически генерируются события "progress”,
// обычно после загрузки каждого файла.
window.applicationCache.onprogress = function(e) {
  // Объект события должен соответствовать событию "progress" (подобному тому,
  // что используется XHR2), что позволяет вычислять процент выполнения,
  // но на всякий случай мы заведем счетчик количества вызовов,
  var progress = "";
  if (е && е.lengthComputable) // Событие "progress": вычислить процент
    progress = " " + Math.round(100*e.loaded/e.total) + "%”
  else // Иначе сообщить кол-во вызовов
    progress = " (" + ++progresscount + ")"
  status("Загружается новая версия" + progress);
  return false;
}
// Когда приложение впервые загружается в кэш, по окончании загрузки
// броузер сгенерирует событие "cached",
window.applicationCache.oncached = function() {
  status("Приложение загружено и установлено локально");
  return false;
};
// Когда обновляется приложение, находящееся в кэше, то по завершении загрузки
// броузер сгенерирует событие "updateready". Обратите внимание, что при этом
// пользователь по-прежнему будет работать со старой версией приложения,
window.applicationCache.onupdateready = function() {
  status("Была загружена новая версия приложения. Перезапустите его.");
  return false;
};
// Если броузер выполняется в автономном режиме и файл объявления не может
// быть проверен, генерируется событие "error". Это же событие генерируется,
// когда некэшированное приложение ссылается на отсутствующий файл объявления,
window.applicationCache.onerror = function() {
  status("Невозможно загрузить файл объявления " +
         "или сохранить приложение в кэш");
  return false;
};
// Если кэшированное приложение ссылается на несуществующий файл объявления,
// генерируется событие "obsolete" и приложение удаляется из кэша.
// В следующий раз приложение будет целиком загружаться из сети, а не из кэша,
window.applicationCache.onobsolete = function() {
  status("3то приложение больше не кэшируется. " +
         "Перезапустите его, чтобы получить последнюю версию из сети.");
  return false;
};

Всякий раз, когда загружается HTML-файл с атрибутом manifest, броузер генерирует событие «checking» и загружает из сети файл объявления. Вслед за событием «checking» в разных ситуациях генерируются разные события:

Нет обновлений

Если приложение уже находится в кэше и файл объявления не изменился, броузер генерирует событие «noupdate».

Есть обновления

Если приложение находится в кэше и обнаружено изменение файла объявления, броузер генерирует событие «downloading» и приступает к загрузке и кэшированию всех файлов, перечисленных в файле объявления. С началом процесса загрузки начинают генерироваться события «progress». А по окончании загрузки генерируется событие «updateready».

Первая загрузка нового приложения

Если приложение отсутствует в кэше, события «downloading» и «progress» генерируются, как и для случая обновления кэше, описанного выше. Однако по окончании первой загрузки броузер генерирует событие «cached», а не «updateready».

Броузер работает в автономном режиме

Если броузер работает в автономном режиме, он не имеет возможности проверить файл объявления и генерирует событие «error». Это же событие генерируется, когда приложение, отсутствующее в кэше, ссылается на отсутствующий файл объявления.

Файл объявления отсутствует

Если броузер подключен к сети и приложение уже установлено в кэш, но при попытке получить файл объявления сервер возвращает ошибку 404 «Not Found», генерируется событие «obsolete» и приложение удаляется из кэша.

Обратите внимание, что все эти события можно отменить. Обработчики в примере 20.4 возвращают значение false, чтобы отменить действия, предусмотренные для событий по умолчанию. Это предотвращает вывод броузером своих собственных сообщений. (На момент написания этих строк ни один броузер не выводил никаких сообщений.)

В качестве альтернативы обработчикам событий, приложение может также использовать свойство applicationCache.status и с его помощью определять состояние кэша. Это свойство может иметь шесть разных значений:

ApplicationCache.UNCACHED (0)

Это приложение не имеет атрибута manifest: оно не кэшируется.

ApplicationCache.IDLE(1)

Файл объявления проверен, и в кэше находится последняя версия приложения.

ApplicationCache.CHECKING (2)

Броузер проверяет файл объявления.

ApplicationCache.DOWNLOADING (3)

Броузер загружает и сохраняет в кэше файлы, указанные в файле объявления.

ApplicationCache.UPDATEREADY (4)

Была загружена и установлена в кэш новая версия приложения.

ApplicationCache.OBSOLETE (5)

Файл объявления отсутствует, и приложение будет удалено из кэша.

Объект ApplicationCache также определяет два метода. Метод update() явно запускает процедуру проверки наличия новой версии приложения. Он заставляет броузер выполнить проверку файла объявления (и сгенерировать сопутствующие события), как если бы приложение загружалось в первый раз.

Метод swapCache() немного сложнее. Напомню, что, когда броузер загрузит и сохранит в кэше обновленную версию приложения, пользователь по-прежнему будет работать со старой версией. Он увидит новую версию, только когда перезагрузит приложение. Если пользователь не сделает этого, старая версия должна работать вполне корректно. И отметьте, что старая версия может по-прежнему загружать ресурсы из кэша: она, например, может использовать объект XMLHttpRequest для загрузки файлов, и эти файлы будут извлекаться из старой версии кэша. То есть, вообще говоря, броузер должен сохранять старую версию кэша, пока пользователь не перезагрузит приложение.

Метод swapCache() сообщает броузеру, что он может удалить старый кэш и удовлетворять все последующие запросы из нового кэша. Имейте в виду, что это не приводит к перезагрузке приложения: HTML-файлы, изображения, сценарии и другие ресурсы, которые уже были загружены, останутся старыми. Но на все последующие запросы будут возвращаться ресурсы из нового кэша. Это может вызвать конфликт между версиями, и в общем случае использовать этот метод не рекомендуется, если только вы специально не предусмотрели такую возможность. Представьте, например, приложение, которое не делает ничего и отображает экранную заставку, пока броузер проверяет файл объявления. Когда приложение получает событие «noupdate», оно продолжает работу и загружает начальную страницу. Если приложение получает событие «downloading», оно отображает соответствующий индикатор хода выполнения операции, пока обновляется кэш. И когда приложение получает событие «updateready», оно вызывает метод swapCache() и затем загружает обновленную начальную страницу из свежей версии в кэше.

Обратите внимание, что вызывать метод swapCache() имеет смысл, только когда свойство status имеет значение ApplicationCache.UPDATEREADY или ApplicationCache.OBSOLETE. (Вызов метода swapCache(), когда свойство status имеет значение OBSOLETE сразу же удалит старую версию кэша, и все ресурсы будут загружаться из сети.) Если вызвать метод swapCache(), когда свойство status имеет любое другое значение, это приведет к исключению.

Оглавление книги


Генерация: 0.534. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз