如何正确使在线/离线Web应用程序的HTML5缓存清单无效?

Jus*_*rls 53 html firefox html5 caching offline-caching

我目前使用一个缓存清单(如描述在这里).这有效地使得在用户离线时运行应用程序所需的资源.

不幸的是,它运作得有点好.

加载缓存清单后,Firefox 3.5+将缓存缓存清单中显式引用的所有资源.但是,如果服务器上的文件已更新,并且用户尝试在线时强制刷新页面(包括缓存清单本身),Firefox将绝对拒绝提取任何内容.应用程序在缓存的最后一点保持完全冻结.问题:

  1. 我希望Firefox在网络连接失败时有效地仅依赖缓存的资源.我尝试过使用FALLBACK块,但无济于事.这甚至可能吗?
  2. 如果#1不可能,那么用户是否可以强制刷新页面并绕过此缓存(ctrl-F5不执行此操作,并且不会清除浏览器的缓存,令人震惊)还没有清除其私有数据?或者,缓存清单机制是否支持到期标头,并且它的行为是否记录在任何地方?

Jus*_*rls 25

我想我已经弄明白了:如果一个缓存清单中出现错误(比如,引用的文件不存在),那么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 }
Run Code Online (Sandbox Code Playgroud)

这当然很有帮助,但我绝对应该要求Mozilla提供一个功能,它至少会将格式错误的缓存清单打印到错误控制台.它不应要求自定义代码附加到这些事件,以将问题诊断为重命名文件.

  • 您可以使用[Manifesto](http://manifesto.ericdelabar.com)书签来验证缓存清单. (2认同)

Dan*_*lor 15

我使用过来自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);
Run Code Online (Sandbox Code Playgroud)


小智 7

免责声明:我对清单和缓存的体验是Safari和FF可能会以不同的方式处理某些事情.

  1. 你太对了.如果清单上列出的任何文件无法找到,则不会发生缓存.

  2. 即使您在线,浏览器也只会检查清单文件.在等待清单文件时,它将继续从缓存加载站点 - 这样不会延迟渲染 - 但这意味着您在第一次加载时看不到任何更改.

  3. 下次加载站点时,如果清单在先前加载时更改,则将加载新文件.

如果有任何变化,总是需要重新开始.事实上,我有时不得不重新加载3次以查看更新.不知道为什么.

在调试时,我使用php动态生成我的清单文件,因此文件名中不会出现拼写错误.我每次都会随机生成版本号以强制更新,但仍然有一个用于测试的脱机webapp.

完成后,php文件可以使用常量版本号回显已保存的清单数据,并始终使用缓存.

我最近在玩清单和缓存时学到的一些东西.它工作得很好,但可能会令人困惑.

没有到期.要取消缓存,您必须更改清单文件以使其中没有任何内容并执行重新加载.在Safari上,清除用户缓存会清除所有缓存的文件.


Oll*_*liM 7

我遇到了同样的问题:一旦Firefox保存了脱机文件,它就不会重新加载它们.Chrome按预期工作,它检查清单文件中的更改,并在清单文件更改时重新加载所有内容.Firefox甚至没有从服务器下载清单文件,因此它无法注意到更改.

经过调查,我发现Firefox正在缓存缓存清单文件(旧式缓存,而不是脱机缓存).设置清单文件的缓存头以Cache-Control: no-cache, private解决问题.