0

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

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

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

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

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

虽然我没有任何具体的证据,但我最终发现的是离开登录页面,而浏览器正在检索 applicationCache 资产的过程中,中断了 appCache 资产的下载并导致离线时无法提供离线资源. 这是预期的浏览器行为吗?如果我等待足够长的时间并让浏览器有机会下载资产,那么离线功能就会起作用。

为了确保离线功能,我是否需要阻止用户离开登录页面,直到触发 applicationCache 缓存事件?

4

1 回答 1

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.

我能想到的一种解决方案是检查beforeunloadthewindow.applicationCache.status是否为checkingdownloading.

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

如果你有很多东西要缓存,你可以显示一个进度条和一些文本,要求用户在页面加载时耐心等待。对于进度条,您可以在缓存处理函数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);
    }
}
于 2013-03-25T12:41:59.713 回答