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


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

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

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

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

6 ответов:

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

чтобы выяснить, что это была проблема, я позаимствовал код из 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 Rocks: обновить кэш:

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, поэтому нет никаких шансов на опечатку в A имя файла. Я также генерирую номер версии случайным образом каждый раз, чтобы принудительно обновить, но все еще имею автономное веб-приложение для тестирования.

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

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

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

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

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

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

http://sites.google.com/site/keigoattic/home/webrelated#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-файлов, которое появляется на начальной странице моего приложения, быстро появилось.

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