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

我当前正在使用“缓存清单”(如此处所述)。 当用户离线时,这有效地使运行应用程序所需的资源可用。

不幸的是,它工作得太好了。

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

  1. 我希望Firefox仅在网络连接失败时才有效地依赖缓存的资源。 我尝试使用FALLBACK块,但无济于事。 这有可能吗?
  2. 如果无法使用#1,那么用户是否有可能在清除其私有数据之前就强行刷新页面并绕过此缓存(ctrl-F5不会这样做,并且清除浏览器的缓存也不会令人震惊)? 另外,高速缓存清单机制是否支持到期标头,并且对此行为在任何地方都有记录吗?
6个解决方案
25 votes

我想我已经弄清楚了:如果一个人的缓存清单中有错误(例如,引用的文件不存在),那么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要求一项功能,该功能至少可以将错误格式的缓存清单打印到错误控制台。 不应要求将自定义代码附加到这些事件上,以将问题诊断为重命名文件一样琐碎。

Justin Searls answered 2020-01-14T09:45:06Z
15 votes

我使用了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);
Danubian Sailor answered 2020-01-14T09:45:26Z
7 votes

免责声明:我在清单和缓存方面的经验是,所有Safari和FF可能在处理某些事情方面均会有所不同。

  1. 你说的很对。 如果清单上列出了任何找不到的文件,则不会进行缓存。

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

  3. 下次加载站点时,如果清单在上一次加载时发生更改,则将加载新文件。

总是需要重新加载两次以查看任何更改。 实际上,有时我不得不重新加载3次才能看到更新。 不知道为什么。

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

一旦完成,php文件就可以使用恒定的版本号回显已保存的清单数据,并且将始终使用缓存。

我最近在玩清单和缓存时学到了一些东西。 它很好用,但可能会造成混淆。

没有有效期。 要取消缓存,您必须将清单文件更改为不包含任何内容并重新加载。 在Safari上,清除用户缓存不会清除所有缓存的文件。

GeoNomad answered 2020-01-14T09:46:22Z
7 votes

我遇到了同样的问题:一旦Firefox保存了脱机文件,就永远不会重新加载它们。 Chrome正常运行,它检查了清单文件是否有更改,如果清单文件发生更改,则重新加载了所有内容。 Firefox甚至没有从服务器下载清单文件,因此它无法注意到更改。

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

OlliM answered 2020-01-14T09:46:47Z
3 votes

我制作了一个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()
keigoi answered 2020-01-14T09:47:21Z
2 votes

嗯,在对清单文件进行编辑更改之后,我只是在缓存上调用了update(),并收到了完整的检查/下载/就绪序列,进行了一次重新加载,并对我在一个js文件中进行的文本更改进行了更改 出现在应用程序初始页面中的文件会立即出现。

似乎我只需要一次重装。

BobFromBris answered 2020-01-14T09:47:46Z
translate from https://stackoverflow.com:/questions/1715568/how-to-properly-invalidate-an-html5-cache-manifest-for-online-offline-web-apps