Как правильно аннулировать манифест кэша HTML5 для онлайн/оффлайн веб-приложений?

StackOverflow https://stackoverflow.com/questions/1715568

Вопрос

В настоящее время я использую манифест кэша (как описано здесь).Это эффективно делает необходимые ресурсы для запуска приложения доступными, когда пользователь находится в автономном режиме.

К сожалению, это работает слишком хорошо.

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

  1. Я хочу, чтобы Firefox эффективно полагался на кэшированные ресурсы только при сбое сетевого подключения.Я пробовал использовать блок FALLBACK, но безрезультатно.Возможно ли это вообще?
  2. Если № 1 невозможен, может ли пользователь принудительно обновить страницу и обойти этот кеш (ctrl-F5 не делает этого, как и очистка кеша браузера, что шокирует), кроме очистки своих личных данных?Альтернативно, поддерживает ли механизм кэш-манифеста заголовки истечения срока действия и задокументировано ли где-нибудь его поведение по отношению к этому?
Это было полезно?

Решение

Кажется, я понял это:если в манифесте кэша есть ошибка (скажем, указанный файл не существует), то Firefox полностью прекратит обработку всего, что связано с кэшем приложения.Это означает, что он не будет ничего обновлять в вашем кеше, включая кэшированный манифест кеша.

Чтобы выяснить, что это была проблема, я позаимствовал код у Mozilla и поместил это в новый (некэшированный) HTML-файл в моем приложении.В последнем зарегистрированном сообщении говорилось, что в моем манифесте кэша может быть проблема, и, конечно же, она была (отсутствующий файл).


// Convenience array of status values
var cacheStatusValues = [];
 cacheStatusValues[0] = 'uncached';
 cacheStatusValues[1] = 'idle';
 cacheStatusValues[2] = 'checking';
 cacheStatusValues[3] = 'downloading';
 cacheStatusValues[4] = 'updateready';
 cacheStatusValues[5] = 'obsolete';

 // Listeners for all possible events
 var cache = window.applicationCache;
 cache.addEventListener('cached', logEvent, false);
 cache.addEventListener('checking', logEvent, false);
 cache.addEventListener('downloading', logEvent, false);
 cache.addEventListener('error', logEvent, false);
 cache.addEventListener('noupdate', logEvent, false);
 cache.addEventListener('obsolete', logEvent, false);
 cache.addEventListener('progress', logEvent, false);
 cache.addEventListener('updateready', logEvent, false);

 // Log every event to the console
 function logEvent(e) {
     var online, status, type, message;
     online = (isOnline()) ? 'yes' : 'no';
     status = cacheStatusValues[cache.status];
     type = e.type;
     message = 'online: ' + online;
     message+= ', event: ' + type;
     message+= ', status: ' + status;
     if (type == 'error' && navigator.onLine) {
         message+= ' There was an unknown error, check your Cache Manifest.';
     }
     log('
'+message); } function log(s) { alert(s); } function isOnline() { return navigator.onLine; } if (!$('html').attr('manifest')) { log('No Cache Manifest listed on the tag.') } // Swap in newly download files when update is ready cache.addEventListener('updateready', function(e){ // Don't perform "swap" if this is the first cache if (cacheStatusValues[cache.status] != 'idle') { cache.swapCache(); log('Swapped/updated the Cache Manifest.'); } } , false); // These two functions check for updates to the manifest file function checkForUpdates(){ cache.update(); } function autoCheckForUpdates(){ setInterval(function(){cache.update()}, 10000); } return { isOnline: isOnline, checkForUpdates: checkForUpdates, autoCheckForUpdates: autoCheckForUpdates }

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

Другие советы

Я использовал код из HTML5-камни:Обновить кэш:

window.addEventListener('load', function(e) {
  if (window.applicationCache) {
    window.applicationCache.addEventListener('updateready', function(e) {
        if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
          // Browser downloaded a new app cache.
          // Swap it in and reload the page to get the new hotness.
          window.applicationCache.swapCache();
          if (confirm('A new version of this site is available. Load it?')) {
            window.location.reload();
          }
        } else {
          // Manifest didn't changed. Nothing new to server.
        }
    }, false);
  }
}, false);

Отказ от ответственности:мой опыт работы с манифестами и кешем показывает, что Safari и FF могут обрабатывать некоторые вещи по-разному.

  1. Ты совершенно прав.Если в манифесте указаны файлы, которые невозможно найти, кэширование не произойдет.

  2. Даже если вы онлайн, браузер проверит только файл манифеста.В ожидании файла манифеста он продолжит загрузку сайта из кеша — таким образом, он не задерживает рендеринг — но это означает, что вы не увидите никаких изменений при первой загрузке.

  3. Если при следующей загрузке сайта манифест изменился при предыдущей загрузке, будут загружены новые файлы.

ВСЕГДА НЕОБХОДИМО ПЕРЕЗАГРУЗИТЬ ДВАЖДЫ, чтобы увидеть какие-либо изменения.Фактически, мне иногда приходилось 3 раза перезагружаться, чтобы увидеть обновление.Понятия не имею, почему.

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

После завершения файл php может просто отображать сохраненные данные манифеста с постоянным номером версии, и кеш всегда будет использоваться.

Просто некоторые вещи, которые я узнал, недавно играя с манифестом и кешем.Это прекрасно работает, но может сбивать с толку.

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

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

После расследования я обнаружил, что Firefox кэшировал файл манифеста кэша (старомодный кеш, а не автономный кеш).Установка заголовка кэша файла манифеста на Cache-Control: no-cache, private решил проблему.

Я сделал надстройку Firefox, которая делает недействительным манифест кэша и очищает локальное хранилище HTML5.

http://sites.google.com/site/keigoattic/home/weblated#TOC-Firefox-HTML5-Offline-Cache-and-Loc

Вы также можете аннулировать манифест кэша, введя приведенный ниже код в консоли ошибок:

// invalidates the cache manifest
var mani = "http://.../mysite.manifest"; // manifest URL
Components.classes["@mozilla.org/network/application-cache-service;1"].getService(Components.interfaces.nsIApplicationCacheService).getActiveCache(mani).discard();

Или, введя приведенный ниже код в адресную строку, вы вручную активируете обновление кеша:

javascript:applicationCache.update()

Хм, я только что вызвал update() в кеше после внесения изменений в файл манифеста и получил полную последовательность проверки/загрузки/готовности, сделал одну перезагрузку и изменение текста, которое я сделал в одном из моих js. файлы, которые отображаются на начальной странице моего приложения, сразу же появились.

Кажется, мне нужна только одна перезагрузка.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top