我正在开发一个供离线使用的Web应用程序,因此我需要使用应用程序缓存功能。
一切在Chrome(15.0.874.106)上运行良好,但在Firefox(7.0.1)和Opera(11.52)上无效。
这是我的缓存清单文件cache.manifest.php
(我已将其减少到最低限度):
<?php
header("Cache-Control: max-age=0, no-cache, no-store, must-revalidate");
header("Pragma: no-cache");
header("Expires: Wed, 11 Jan 1984 05:00:00 GMT");
header('Content-type: text/cache-manifest');
?>CACHE MANIFEST
CACHE:
/app/common/css/reset.css
/favicon.ico
这是“主要”HTML文档的前4行:
<!DOCTYPE html>
<html manifest="/app/mobile/cache.manifest.php">
<head>
<title>MyApp Mobile</title>
当我尝试将缓存清单(http://www.myapp.com/app/mobile/cache.manifest.php)加载到浏览器中时,文件显示正确,但是当我尝试离线加载页面时我收到“无法连接”错误页面。再次,这恰好发生在Firefox和Opera上。
Firebug说“0 items in offline cache
”,我没有找到检查DragonFly上的应用程序缓存的方法。
我生气了,我不知道如何在Firefox和Opera上有效地调试问题。 请帮忙。
谢谢, 丹
答案 0 :(得分:15)
根据我使用HTML5 AppCache的经验,一旦你开始工作就很棒,但非常脆弱。如果有最小的问题,浏览器会忽略整个文件,而且令人烦恼的是,不是使用浏览器的普通缓存,而是从服务器上重新加载所有内容。
更糟糕的是,除非文字内容发生变化,否则浏览器将不会重新加载清单文件。所以你可能会调整你的服务器标题或其他东西来修复它,但除非cache.manifest.php
的内容发生变化,否则浏览器会盲目地忽略它并完全按照上次的行为。所以它可能已被破坏,然后你修复了它,但是浏览器忽略了这些变化,因为cache.manifest.php
的文本内容没有改变。这甚至似乎不会清除你的浏览器缓存,这是令人困惑的一部分 - 应用程序缓存对于缓存非常非常认真。
要解决这个问题,注释中的文本更改会发生变化,因此请在顶部添加带有版本或时间戳或日期(例如# Version 1.2
)的注释,并在您希望浏览器“注意”时更改该注释。
然后,浏览器仍然不会立即使用它!应用程序缓存的工作方式是下次加载页面时,它将完全按照上次执行的操作再次执行,并开始在后台检查更新。所以你可能想要控制台,等待“更新......”然后“完成”,然后点击刷新,浏览器最终将开始使用新版本。最后!
总而言之,开始工作可能是一种正确的痛苦。然而,一旦它正在工作它几乎是防弹的:你几乎可以放心,缓存清单中列出的任何内容只有每次下载一次,永远,每个用户,直到您更改文件的文本内容。
浏览器标准合规性现在相当不错,所以我最好的猜测是你实际上有它工作,但你最后检查了Chrome,它是唯一正确缓存了清单文件的浏览器。在开发过程中,你可能已经破坏了它,但Firefox和Opera正在抓住他们的旧清单文件。我打赌你还尝试清除Firefox和Opera中的浏览器缓存,它可能什么也没做 - 你需要更改文件的文本内容并进行双重刷新,之后Firefox和Opera最终会放弃清单版本的清单文件和开始使用你很久以前上传过的那个。
答案 1 :(得分:9)
来自:http://appcache.offline.technology
在Firefox中,任何使用Cache-control:no-store提供的资源都不会被缓存,即使它们已明确包含在清单中。
我的php默认发送:
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
添加:
就足够了header("Cache-Control: no-cache, must-revalidate");
到php文件让它开始缓存它。
(这与Mychal Hackman的答案类似,但更具体一点)。
答案 2 :(得分:3)
对我来说,你的缓存清单看起来有些“不寻常”...它可能有助于添加FALLBACK
部分...另一点是appcache可能会干扰“正常的浏览器缓存”,即如果缓存清单已更改,需要确保浏览器重新加载它,理想情况下,这是通过更改名称来实现的(例如,通过将版本号,时间戳...作为名称的一部分)。
您可以通过JS在appcache中与您的页面进行交互,这有助于查明您看到的问题。
有关包括JS代码在内的深入信息和详尽的演练,请参阅
如果需要回答具体问题。
更新
根据OP this提供的评论显示了一个很好的JS API实现,用于检查/调试appcache,如上面的链接所述。
答案 3 :(得分:3)
您可以使用window.applicationCache.status
检查应用程序缓存的当前状态,该值返回映射到以下状态的数值:
0 - uncached
,1 - idle
,2 - checking
,3 - downloading
,4 - updateready
,5 - obsolete.
应用程序缓存API有一些值得注意的事情:
window.applicationCache.update()
:这将触发应用程序缓存下载过程,这与重新加载页面几乎相同。它只是检查清单是否已更改,如果是,则下载缓存中所有内容的新版本(尊重任何缓存头)。请注意,即使使用此创建新缓存,页面仍将继续使用旧缓存。要使页面使用刚下载的新缓存,必须使用swapCache()
函数。
window.applicationCache.swapCache()
:此函数告诉浏览器开始使用新缓存数据(如果可用)。请务必注意,即使存在新的清单文件,应用程序仍将继续使用旧缓存(如旧清单文件中所指定),直至调用swapCache()
。调用swapCache()
后,将按照新清单文件中的指定使用缓存。
来自: http://dev.opera.com/articles/view/offline-applications-html5-appcache/
答案 4 :(得分:3)
在about:cache
中检查您的缓存。我打赌你会看到PHP文件的“数据大小为0字节”。
检查你的缓存标题,我在Firefox中发现我的php文件默认为“no-cache”。我刚补充说:
header("Pragma: public");
header("Cache-Control: public, max-age=6000");
到我的PHP文件并重新加载离线缓存,它终于正常工作。
HTH
答案 5 :(得分:2)
尝试删除:
header("Cache-Control: max-age=0, no-cache, no-store, must-revalidate");
header("Pragma: no-cache");
header("Expires: Wed, 11 Jan 1984 05:00:00 GMT");
以便您只发送Content-type标题:
<?php header('Content-type: text/cache-manifest'); ?>
ApplicationCache强制缓存(过度简化,但不是太多)。前三个标题是防止缓存的方法。
当这些标头存在时,Opera似乎会阻止缓存。在调试AppCache时,Firefox的调试工具有点不稳定,但可能会假设这也会在那里修复它。
答案 6 :(得分:2)
对于Firefox,尝试这个小技巧:
<html manifest="/app/mobile/cache.manifest.php?1">
它的&#34;?1&#34;最终让Firefox检查最新文件。无论如何,这对我来说是什么伎俩。希望这会有所帮助。
答案 7 :(得分:1)
根据我在iPad上离线工作的经验:
.manifest
text/cache-manifest
window.applicationCache...
创建一些javascript函数,以检查浏览器是否看到清单中的更改并重新加载内容,还捕获状态事件并将其显示在某处答案 8 :(得分:1)
我有类似的问题。我很晚才回答,但这可能对其他人有帮助。确保你没有遇到AshleysBrian在他的回答中描述的问题。添加到
离线时,网址的简单更改可能是个问题
Eg: http://localhost:8080/app doesn't work on Firefox/IE
but http://localhost:8080/app/ works in Firefox/IE
它们都可以在Chrome中使用
使用这些方便的资源查看器获取更详细的视角
about:cache - Firefox
chrome://appcache-internals/ - Chrome
Pls fill in if someone knows what is it for IE
答案 9 :(得分:0)
据我了解,W3C HTML5草案中的脱机Web应用程序部分是非规范性的;这意味着它仍然不是正式的HTML5标准的一部分。
由于该功能仍然不是HTML5标准的一部分,因此不同的浏览器可能具有不同的和变化的/非标准的实现,如果他们选择实现它的话。并非所有浏览器都可以选择支持它。在它们成为标准的一部分之前,不要依赖非规范性功能。
答案 10 :(得分:0)
我发现了类似的东西,并将其跟踪到清单上的Cache-Control:no-store标题。 Chrome接受了这一点,但Firefox无声地失败了。
我的测试显示您可以保留no-cache标头&amp;将标题过期以确保频繁刷新。
答案 11 :(得分:0)
让清单在任何地方工作的唯一方法就是这样做:
CACHE MANIFEST
# version x.x
# 2015-03-27
# list everything
如果我使用NETWORK
和/或FALLBACK
,则无法使用(在Chrome中)。
答案 12 :(得分:-1)
我也有同样的问题。在Chrome和IE浏览器中,一切都运行良好,但是无法连接&#34; FF中的消息。
经过几个小时的绝望之后,我找到了解决方案,这很荒谬简单: 在开发人员工具栏中,整个缓存已停用。 :/