【问题标题】:HTML5 - cache manifest working great on Chrome but not on Firefox and OperaHTML5 - 缓存清单在 Chrome 上运行良好,但在 Firefox 和 Opera 上不可用
【发布时间】:2015-12-07 02:39:28
【问题描述】:

我正在开发一个供离线使用的网络应用程序,因此我需要使用应用程序缓存功能。

在 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 上有效地调试问题。 请帮忙。

谢谢, 丹

【问题讨论】:

  • 只是为了确保您确实首先打开了“主”HTML 文档并允许 Firefox 为您的站点离线存储数据?你没有明确说明。简化的非工作版本是否在网上某处可用?我敢打赌这会让回答更容易。
  • 好点:我确实让 Firefox 有机会通过打开 Internet 来存储缓存清单。一旦我关闭互联网并重新加载页面,它就不再工作了 - 它给了我“无法连接”的消息。
  • @dan,你为什么不把 main 页面添加到缓存中..
  • @muntoo:正如我所说,我要生气了。我已经快一年没有被技术产品阻止了。
  • @Gaby:主页应该默认缓存,我读过。你说得对,我要试试。

标签: html firefox opera offline application-cache


【解决方案1】:

根据我使用 HTML5 AppCache 的经验,一旦你开始使用它就很棒,但它非常脆弱。如果它有最微小的问题,浏览器会忽略整个文件,而且令人讨厌的是,它不会使用浏览器的普通缓存,而是从头开始重新加载服务器上的所有内容。

更糟糕的是,浏览器不会重新加载清单文件,除非其文本内容发生变化。所以你可能会调整你的服务器头或其他东西来修复它,但除非cache.manifest.php 的内容更改,否则浏览器会盲目地忽略它并完全按照上次所做的 .所以它可能已经坏了,然后你修复了它,但是浏览器忽略了这些变化,因为 cache.manifest.php 的文本内容没有改变。这甚至似乎对清除浏览器缓存免疫,这也是造成它如此混乱的部分原因 - 应用缓存对缓存非常非常重要。

为了解决这个问题,cmets 中的文本更改很重要,因此请在顶部添加带有版本或时间戳或日期的注释(例如 # Version 1.2),并在您希望浏览器“通知”时更改它。

那么,浏览器仍然不会立即使用它!应用缓存的工作方式是下次加载页面时,它会再次和上次一样,并开始在后台检查更新。因此,您可能希望控制台启动,等待“更新...”然后“完成”,然后点击刷新,浏览器最终将开始使用新版本。终于!

总而言之,开始工作可能是一种痛苦。但是,一旦它开始工作,它几乎是万无一失的:您几乎可以放心,缓存清单中列出的任何内容都是每次下载一次曾经,一直以来,每个用户,直到您更改文件的文本内容。

这些天浏览器标准的合规性非常好,所以我最好的猜测是你确实让它工作了,但你最后检查了 Chrome,它是唯一正确缓存清单文件的浏览器。在开发过程中,你可能已经把它弄坏了,但是 Firefox 和 Opera 死死抓住他们的旧清单文件。我敢打赌,您还尝试清除 Firefox 和 Opera 中的浏览器缓存,这可能什么也没做 - 您需要更改文件的文本内容并在 Firefox 和 Opera 最终放弃其损坏的清单文件版本之前进行两次刷新开始使用您可能很久以前上传的那个有效的。

【讨论】:

  • 感谢您的帮助。事实是应用缓存根本不起作用 - 使用旧版本不是问题。
  • 另一种解决方案是生成缓存清单文件并在清单中包含所有文件的 MD5。这样,如果 ANY 文件发生更改,清单也会更改(因为文件的 MD5 已更改)。
【解决方案2】:

发件人: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 的回答,但更具体一些)。

【讨论】:

    【解决方案3】:

    对我来说,您的缓存清单看起来有点“不寻常”...添加FALLBACK 部分可能会有所帮助...另一点是应用缓存可能会干扰“正常浏览器缓存”,即如果缓存清单更改它需要确保浏览器重新加载它,理想情况下这是通过更改名称来实现的(例如,通过将版本号、时间戳...作为名称的一部分)。

    您可以在页面中通过 JS 与 appcache 进行交互,这有助于查明您看到的问题。

    有关包括 JS 代码和全面演练在内的深入信息,请参阅

    如果需要返回具体问题。

    更新

    根据 OP this 提供的 cmets 显示了一个很好的 JS API 实现,用于检查/调试应用缓存,如上面的链接中所述。

    【讨论】:

    • 这是一个关于如何使用 JS 调试 appcache 的好链接:jonathanstark.com/blog/2009/09/27/…
    • @dan 不客气 :-) 是的,该链接提供了一个很好的实现...将其添加到答案中以供将来参考。
    【解决方案4】:

    您可以使用window.applicationCache.status 检查应用程序缓存的当前状态,它会返回一个映射到以下状态的数值: 0 - uncached1 - idle2 - checking3 - downloading4 - updateready5 - obsolete.

    应用缓存 API 有几点值得注意: window.applicationCache.update():这会触发应用缓存下载过程,和重新加载页面差不多。它只是检查清单是否已更改,如果是,则下载缓存中所有内容的新版本(尊重任何缓存标头)。请注意,即使使用它创建了新缓存,页面仍将继续使用旧缓存。要让页面使用刚刚下载的新缓存,必须使用swapCache()函数。

    window.applicationCache.swapCache():此函数告诉浏览器开始使用新的缓存数据(如果可用)。需要注意的是,即使有新的清单文件,应用程序仍将继续使用旧缓存(如旧清单文件中指定的那样),直到调用 swapCache()。调用swapCache() 后,将按照新清单文件中的指定使用缓存。

    来自: http://dev.opera.com/articles/view/offline-applications-html5-appcache/

    【讨论】:

      【解决方案5】:

      检查about:cache 中的缓存。我打赌你会看到你的 PHP 文件的“data-size 0 bytes”。

      检查您的缓存标头,我发现在 Firefox 中,我的 php 文件默认设置为“无缓存”。我刚刚补充了:

      header("Pragma: public");
      header("Cache-Control: public, max-age=6000");
      

      到我的 PHP 文件并重新加载离线缓存,它终于可以工作了。

      HTH

      【讨论】:

        【解决方案6】:

        尝试删除:

        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 似乎会阻止缓存。 Firefox 的调试工具在调试 AppCache 时有点不稳定,但假设这也能修复它可能是省事的。

        【讨论】:

        • 有趣的一点,webinista。我能预见的唯一问题(也是一个大问题)是即使内容发生变化,浏览器也不会更新缓存清单,因为文件将被缓存。对此有什么想法吗?你有任何链接支持你的理论吗?
        • 人力资源部。看起来这些标题毕竟不会有太大区别。也就是说,如果缓存清单文件更改,浏览器将更新缓存。因此,如果您在 reset.css 中进行更改,请通过添加或更改注释来更改 cache.manifest.php。要尝试的另一件事:使用 JavaScript 添加清单属性。
        • “使用 JavaScript 添加清单属性” - 有趣的想法:你认为这有什么帮助?另外,我应该什么时候添加它?
        • 好吧,我有一个类似的问题,发送Cache-control: no-store 导致 Firefox 拒绝清单(window.applicationCache error 事件被调用)。因此,显然 Firefox 对 HTTP 标头很敏感。 OTOH,Firefox 接受 Cache-control: no-cachePragma: no-cacheExpires: 0
        【解决方案7】:

        对于 Firefox,试试这个小技巧:

        <html manifest="/app/mobile/cache.manifest.php?1"> 
        

        它的“?1”最终让 Firefox 检查最新文件。无论如何,这就是我的诀窍。希望这会有所帮助。

        【讨论】:

          【解决方案8】:

          根据我让网站在 iPad 上离线工作的经验:

          • 文件名需要以.manifest结尾
          • mime 类型需要为text/cache-manifest
          • 在清单的 cmets 中有一个版本
          • 使用 window.applicationCache... 创建一些 javascript 函数来检查浏览器是否看到清单中的更改并重新加载内容,同时捕获状态事件并将它们显示在某处

          另请参阅: http://developer.apple.com/library/safari/#documentation/iPhone/Conceptual/SafariJSDatabaseGuide/OfflineApplicationCache/OfflineApplicationCache.html#//apple_ref/doc/uid/TP40007256-CH7-SW1

          【讨论】:

          • 您不需要包含html页面本身,它会自动包含。
          【解决方案9】:

          我遇到了类似的问题。我回答得很晚,但这可能对其他人有帮助。确保您不会遇到 AshleysBrian 在他的回答中描述的问题。添加到那个

          1. 确保清单文件以“text/cache-manifest”类型提供
          2. 不要在 Firefox/IE 的隐私浏览模式下尝试。它仅适用于常规浏览模式。但它在 Chrome 中的两种模式下都有效
          3. 离线时,对 URL 的简单更改可能会出现问题

            Eg: http://localhost:8080/app doesn't work on Firefox/IE
            but http://localhost:8080/app/ works in Firefox/IE 
            

            它们都在 Chrome 中工作

          4. 使用这些方便的资源查看器获得更详细的视角

            about:cache - Firefox
            chrome://appcache-internals/ - Chrome
            Pls fill in if someone knows what is it for IE
            

          【讨论】:

            【解决方案10】:

            据我了解,W3C HTML5 草案中的离线 Web 应用程序部分是非规范性的;这意味着它仍然不是正式的 HTML5 标准的一部分。

            由于该功能仍然不是 HTML5 标准的一部分,不同的浏览器可能有不同的和变化的/非标准的实现,如果他们选择实现它的话。并非所有浏览器都可以选择支持它。在非规范性特征成为标准的一部分之前,不要依赖它们。

            【讨论】:

            • 由于 W3C 进程的速度,HTML5 都不是“正式标准”。
            • 只有部分 HTML5 规范已标准化。规范特性的实现适用于所有浏览器,而非规范特性则不行。所以,不要指望 IE、firefox、opera 等在没有标准规范的情况下也会以同样的方式工作。
            • OP 不希望它以相同的方式工作,他要求就特定问题和调试提出建议。我不是在争论你的说法,我只是说这不是问题的答案:)
            • @Vikas,感谢您的回答,但我已经在 Internet 上检查过,我使用的 Firefox 和 Opera 的版本都支持应用程序缓存。
            • @dan,我建议参考特定的浏览器文档,了解支持的功能的语法和语义。您可能需要为每个浏览器添加特定的实现。
            【解决方案11】:

            我发现了类似的东西,并将其追踪到清单上的 Cache-Control: no-store 标题。 Chrome 接受这一点,但 Firefox 会默默地失败。

            我的测试表明,您可以保留无缓存标头和过期标头以确保频繁刷新。

            【讨论】:

              【解决方案12】:

              让清单在任何地方都能正常工作的唯一方法是这样做:

              CACHE MANIFEST
              # version x.x
              # 2015-03-27
              
              # list everything
              

              如果我使用 NETWORK 和/或 FALLBACK,它将无法工作(在 Chrome 中)。

              【讨论】:

                【解决方案13】:

                我也遇到了同样的问题。在 Chrome 和 IE 中一切正常,但在 FF 中出现“无法连接”消息。

                经过数小时的绝望后,我找到了解决方案,这非常简单: 在开发者工具栏中,整个缓存被停用。 :/

                【讨论】:

                • 虽然这可能会回答问题,但请您通过在答案中添加更多细节来扩展。就目前而言,您还没有真正解释如何解决问题。
                • 你的答案必须更明确
                猜你喜欢
                • 1970-01-01
                • 2014-10-13
                • 2014-11-19
                • 2011-12-23
                • 2018-09-25
                • 1970-01-01
                • 1970-01-01
                • 2018-02-04
                • 1970-01-01
                相关资源
                最近更新 更多