如何正确无效的在线/离线networking应用程序的HTML5caching清单?

我正在使用caching清单(如此处所述)。 这有效地提供了必要的资源,以便在用户脱机时运行可用的应用程序。

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

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

  1. 我希望Firefox在networking连接失败时只能依靠caching的资源。 我试过使用FALLBACK块,但无济于事。 这甚至有可能吗?
  2. 如果#1是不可能的,用户是否有可能强制刷新一个页面并绕过这个caching(ctrl-F5不这样做,也没有清除浏览器的caching,令人震惊的是)没有清除他们的私人数据? 或者,cache-manifest机制是否支持expiry头文件,并且是否在任何地方logging了它的行为?

我想我已经得出了这个想法:如果一个人的caching清单中存在错误(例如,一个引用的文件不存在),那么Firefox将完全停止处理任何与applicationCache相关的东西。 意思是,它不会更新caching中的任何内容,包括caching的caching清单。

为了发现这个问题,我从Mozilla借了一些代码,并将其放到我的应用程序中的一个新的(非caching的)HTML文件中。 logging的最后一条消息指出,在我的caching清单中可能存在问题,并且确实存在(缺less文件)。

// 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申请一个function,将错误的caching清单打印到错误控制台。 它不应该要求自定义代码附加到这些事件来诊断问题,如重命名文件一样微不足道。

我使用了HTML5 Rocks的代码:更新caching :

 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); 

免责声明:我对清单和caching的经验是所有的Safari和FF可以处理一些不同的事情。

  1. 你太对了。 如果清单中列出的文件中找不到任何文件,则不会发生caching。

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

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

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

在debugging的时候,我用php生成了我的清单文件,所以在文件名中没有input错误的机会。 我也每次随机生成版本号来强制更新,但仍然有一个离线的Web应用程序进行testing。

一旦完成,php文件可以用一个恒定的版本号回显已保存的清单数据,caching将一直使用。

只是我最近玩清单和caching时学到了一些东西。 它工作的很好,但可以混淆。

没有到期。 要取消高速caching,必须更改清单文件以使其中没有任何内容,然后重新加载。 在Safari上,清除用户caching清除所有caching的文件。

我有同样的问题:一旦Firefox保存脱机文件,它不会重新加载它们。 Chrome按预期工作,它检查清单文件的更改,如果清单文件更改,则重新加载所有内容。 Firefox甚至没有从服务器上下载清单文件,所以它没有注意到变化。

经过调查,我发现Firefox正在cachingcaching清单文件(老式的caching,而不是离线caching)。 设置清单文件的caching头为Cache-Control: no-cache, private解决了这个问题。

我做了一个Firefox插件,使Cache Manifest无效并清除HTML5本地存储。

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

您也可以通过在错误控制台中键入以下代码来使caching清单无效:

 // 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(); 

或者,通过在地址栏中input下面的代码将手动enforececaching进行更新:

 javascript:applicationCache.update() 

嗯,我只是在caching中调用了update(),在对manifest文件进行了编辑之后,接收到了完整的check / downloaded / ready序列,做了一个重载,并在我的一个js中做了文本更改文件,显示在我的应用程序的初始页面,及时出现。

似乎我只需要一个重新加载。