如何确保下载所有应用程序缓存资源?

时间:2012-07-16 19:56:59

标签: html5 offline offline-caching

我一直在遇到最初似乎是间歇性的问题,我的应用程序无法脱机工作。

关于我的申请的一些细节:

  • 我的应用程序的入口点是登录页面
  • 我的应用程序中的所有页面,除登录页面外,都显示动态数据。为了确保不缓存显示动态数据的页面,我选择只让Login页面在其html元素中包含manifest属性。
  • 我的清单文件中列出的资产总大小约为1MB。

我重现问题的步骤(假设我没有在我的浏览器/设备上缓存applicationCache资源):

  • 导航到登录页面(applicationCache资源将开始下载)
  • 立即登录该应用程序
  • 离线并请求离线资源
  • 请注意,浏览器无法从applicationCache
  • 提供资源

虽然我没有任何具体的证据,但我最终发现的是导航离开Login页面,而浏览器正在检索applicationCache资产,中断appCache资产的下载并导致脱机资源无法提供离线时启动这是预期的浏览器行为吗?如果我等待足够的时间并让浏览器有机会下载资产,则可以使用离线功能。

为了确保脱机功能,我是否需要阻止用户从“登录”页面导航,直到触发applicationCache缓存事件?

1 个答案:

答案 0 :(得分:1)

  

这是预期的浏览器行为吗?

这确实是预期的行为。见http://diveintohtml5.info/offline.html#debugging

if even a single resource listed in your cache manifest file fails to download properly, the entire process of caching your offline web application will fail. Your browser will fire the error event, but there is no indication of what the actual problem was.

我能想到的一个解决方案是检查beforeunload window.applicationCache.statuschecking还是downloading

或者您可以在用户localStorage中设置一个标志,指示上次尝试未成功,使用error事件(见下文)并尝试重新获取文件,直到所有内容都成功加载。

如果你有很多要缓存的东西,你可以显示一个进度条和一些文本,要求用户在页面加载时保持耐心。对于进度条,您可以在缓存处理函数的progress事件中使用event.loadedevent.total

var appCache = window.applicationCache;

// Fired after the first cache of the manifest.
appCache.addEventListener('cached', handleCacheEvent, false);

// Checking for an update. Always the first event fired in the sequence.
appCache.addEventListener('checking', handleCacheEvent, false);

// An update was found. The browser is fetching resources.
appCache.addEventListener('downloading', handleCacheEvent, false);

// The manifest returns 404 or 410, the download failed,
// or the manifest changed while the download was in progress.
appCache.addEventListener('error', handleCacheError, false);

// Fired after the first download of the manifest.
appCache.addEventListener('noupdate', handleCacheEvent, false);

// Fired if the manifest file returns a 404 or 410.
// This results in the application cache being deleted.
appCache.addEventListener('obsolete', handleCacheEvent, false);

// Fired for each resource listed in the manifest as it is being fetched.
appCache.addEventListener('progress', handleCacheEvent, false);

// Fired when the manifest resources have been newly redownloaded.
appCache.addEventListener('updateready', handleCacheEvent, false);

function handleCacheEvent(e){
    if(e.type && (e.type=='progress' || e.type=='ProgressEvent')){
        console.log('percent:', Math.round(e.loaded/e.total*100)+'%', 'total:', e.total, 'loaded:',e.loaded);
    }
}