HTML5 应用程序缓存

Posted thgj0006

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTML5 应用程序缓存相关的知识,希望对你有一定的参考价值。

html5 应用程序缓存


使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本。这意味着,你可以在没有网络连接的情况下进行访问。


什么是应用程序缓存(Application Cache)?

HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问。

应用程序缓存为应用带来三个优势:

  1. 离线浏览 - 用户可在应用离线时使用它们
  2. 速度 - 已缓存资源加载得更快
  3. 减少服务器负载 - 浏览器将只从服务器下载更新过或更改过的资源。

浏览器支持

Internet Explorer 10, Firefox, Chrome, Safari 和 Opera 支持应用程序缓存.


HTML5 Cache Manifest 实例

下面的例子展示了带有 cache manifest 的 HTML 文档(供离线浏览):

实例

<!DOCTYPE HTML>
<html manifest="demo.appcache">

<body>
The content of the document......
</body>

</html>


尝试一下 »


Cache Manifest 基础

如需启用应用程序缓存,请在文档的<html> 标签中包含 manifest 属性

<!DOCTYPE HTML>
<html manifest="demo.appcache">
...
</html>

每个指定了 manifest 的页面在用户对其访问时都会被缓存。如果未指定 manifest 属性,则页面不会被缓存(除非在 manifest 文件中直接指定了该页面)。

manifest 文件的建议的文件扩展名是:".appcache"。

请注意,manifest 文件需要配置正确的 MIME-type,即 "text/cache-manifest"。必须在 web 服务器上进行配置。


Manifest 文件

manifest 文件是简单的文本文件,它告知浏览器被缓存的内容(以及不缓存的内容)。

manifest 文件可分为三个部分:

  • CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存
  • NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存
  • FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)

CACHE MANIFEST

第一行,CACHE MANIFEST,是必需的:

CACHE MANIFEST
/theme.css
/logo.gif
/main.js

上面的 manifest 文件列出了三个资源:一个 CSS 文件,一个 GIF 图像,以及一个 javascript 文件。当 manifest 文件加载后,浏览器会从网站的根目录下载这三个文件。然后,无论用户何时与因特网断开连接,这些资源依然是可用的。

NETWORK

下面的 NETWORK 小节规定文件 "login.php" 永远不会被缓存,且离线时是不可用的:

NETWORK:
login.php

可以使用星号来指示所有其他其他资源/文件都需要因特网连接:

NETWORK:
*

FALLBACK

下面的 FALLBACK 小节规定如果无法建立因特网连接,则用 "offline.html" 替代 /html5/ 目录中的所有文件:

FALLBACK:
/html/ /offline.html

注意: 第一个 URI 是资源,第二个是替补。


更新缓存

一旦应用被缓存,它就会保持缓存直到发生下列情况:

  • 用户清空浏览器缓存
  • manifest 文件被修改(参阅下面的提示)
  • 由程序来更新应用缓存

实例 - 完整的 Manifest 文件

CACHE MANIFEST
# 2012-02-21 v1.0.0
/theme.css
/logo.gif
/main.js
NETWORK:
login.php

FALLBACK:
/html/ /offline.html

提示:以 "#" 开头的是注释行,但也可满足其他用途。应用的缓存会在其 manifest 文件更改时被更新。如果您编辑了一幅图片,或者修改了一个 JavaScript 函数,这些改变都不会被重新缓存。更新注释行中的日期和版本号是一种使浏览器重新缓存文件的办法。


关于应用程序缓存的说明

请留心缓存的内容。

一旦文件被缓存,则浏览器会继续展示已缓存的版本,即使您修改了服务器上的文件。为了确保浏览器更新缓存,您需要更新 manifest 文件。

注意: 浏览器对缓存数据的容量限制可能不太一样(某些浏览器设置的限制是每个站点 5MB)。

我的 HTML5 应用程序缓存清单正在缓存所有内容

【中文标题】我的 HTML5 应用程序缓存清单正在缓存所有内容【英文标题】:My HTML5 Application Cache Manifest is caching everything 【发布时间】:2012-03-06 10:05:32 【问题描述】:

更新:

** 当这个功能真的很新时,我发布了这个问题,我现在意识到这个功能不应该以这种方式使用,除非它是通过 JavaScript 使用的。但对于大多数犯同样错误和滥用此功能的初学者来说,似乎这个 hack 是一个很好的解决方案。如果你想缓存除 HTML 之外的所有内容,这应该使用 JS 来完成,或者你可以使用下面的解决方案 **

我想我的问题可以归结为: 如果使用 HTML 标记的 manifest 属性引用清单的文件属于 MASTER CACHE ENTRIES,您如何让动态页面使用清单。

我的文件如下所示:

CACHE MANIFEST

CACHE:
# IMAGES:
/stylesheets/bg.jpg
/stylesheets/cont_bg.png
#and so forth.. 

#EXTERNAL
http://chat.mydomain.com/themes/images/panel_bg.png
http://chat.mydomain.com/themes/images/images_core.png

####################################
#STYLE SHEETS:
/stylesheets/min.css
/stylesheets/css_night.aspx

#####################################
#JAVASCRIPT:
/JAVASCRIPT/header_javascript.js

#EXTERNAL:
http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js
http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js

FALLBACK:
/ /offline.php

NETWORK:
*

现在的问题是,一旦我浏览一个不在清单中的页面,我的实际动态 php 文件(如 index.php),当我第一次看到该页面并且没有缓存 chrome 时:

Adding master entry to Application Cache with manifest http://208.109.248.197/manifest.appcache

Application Cache Downloading event
Application Cache Progress event (0 of 28) 
...
Application Cache Progress event (28 of 28) 
Application Cache NoUpdate event

到目前为止一切顺利,直到我真正加载了一个页面,并且 chrome 运行:

Application Cache UpdateReady event
Adding master entry to Application Cache with manifest http://mydomain.com/manifest.appcache

现在正如您在最后一行中看到的那样,它将 index.php 添加到我的应用程序缓存中,我已经通过访问 url 验证了这一点:chrome://appcache-internals/

上面写着:

Flags   URL Size (headers and data)
Explicit,   http://mydomain/JAVASCRIPT/header_javascript.js 57.5 kB
Master, http://mydomain/home.php 51.2 kB
Master, http://mydomain/index.php   53.5 kB
Master, Fallback,   http://mydomain/offline.php 49.4 kB

像 index.php 和 home.php 这样的东西不应该被缓存。如果可能,我想告诉它不要缓存任何 html 扩展。但这是我从各种 RFC 中学到的东西,我相信: 在线白名单通配符标志,打开或阻止。

The open state indicates that any URL not listed as cached is to be implicitly treated as being in the online whitelist namespaces; the blocking state indicates that URLs not listed explicitly in the manifest are to be treated as unavailable.

好吧,我想使用这些在线白名单通配符标志之一并将其设置为阻止,但我找不到更多解释或示例。 我也读过:

zero or more URLs that form the online whitelist namespaces.

These are used as prefix match patterns, and declare URLs for which the user agent will ignore the application cache, instead fetching them normally (i.e. from the network or locale HTTP cache as appropriate).

我也想使用这样的模式,但我又找不到任何文档。为什么没有 appcache 清单文档的迹象,而且我去过的其他网站也没有使用它,因为我的 chrome appcache 目录没有显示!?!?

感谢您的宝贵时间!

【问题讨论】:

【参考方案1】:

这是我在玩耍时发现的一个技巧:

我还没有找到最终的答案,但据我所知,清单似乎并不是要在每个页面上设置。我再次不确定,但这是我遇到的一个黑客。我有一个页面,例如 manifest.html 有

<html manifest="manifest.appcache"> 

我了解到没有此功能的页面不会被添加到缓存中,但是如果它们位于同一域中,它们仍将继续使用应用程序缓存。因此,如果您包含 manifest.html 一个普通的 html 页面,该页面在每个页面的 iframe 中都有它,它不会像 chrome 一样缓存该页面将不再输出:

Adding master entry to Application Cache with manifest 

但是如果你去网络选项卡你会看到它正在使用缓存

<iframe id='manifest_iframe_hack' 
  style='display: none;' 
  src='temporary_manifest_hack.html'>
</iframe> 

temporary_manifest_hack.html 的内容:

<!DOCTYPE HTML>
<html lang="en" class="no-js" manifest="manifest.appcache">
    <head>
        <meta charset="utf-8">
        <title>Hack 4 Manifest</title>
    </head>
    <body></body>
</html>

【讨论】:

我明白,我的意思是:你如何在不包括主 html 页面本身的情况下使用应用程序缓存并将其引入浏览器......如果这有意义的话。 @Neo 您可以使用“no-store”缓存指令来提供您不想缓存的主页。 你能提供一个工作示例的链接吗?这对我不起作用,我可以看到 appcache 初始化日志消息,但是尽管有缓存,我的 JS 和 CSS 仍在加载。 @Sam 也许对 JS 和 CSS 有一个无缓存标头?初始化时,你看到列表中的 JS 和 CSS 文件了吗? Chrome 在控制台中显示整个列表。您是否在 appcache.manifest 文件中列出了这些文件? 是的,它的实现似乎已经改变,因为在我写这个 Chrome 的时候确实从缓存中加载了文件。【参考方案2】:

appcache 始终包含在 html 标记中包含 manifest 属性的页面。

如果您希望该页面本身是动态的,则必须通过对 NETWORK 部分中的服务的 ajax 调用将内容加载到其中。

【讨论】:

+1 这是一个更好的方法。当我写这个问题时,应用程序缓存是新的,包括我自己在内的许多人都将它用于快速缓存解决方案,而无需处理 HTTP 标头,我仍然认为如果完全理解它可以用作黑客,你的建议是使用这项技术的正确方法,我的答案是如何将它用作缓存静态内容的黑客,在完全 ajaxified 的动态页面上。 @Joeri 它仍然会将该页面保存在 appcache 中,因此如果您有很多路由(例如 domain.com/userId ),它将无法工作。【参考方案3】:

我猜 Iframe 解决方法不起作用。如果您认为文件是从 appcache 加载的:否。它们来自浏览器缓存。

在开发工具设置中禁用浏览器缓存并查看“网络”。您可以看到,所有元素都将通过网络加载,而不是来自(应用)缓存。

【讨论】:

那你肯定没有在你的appcache清单中指定文件。你看到初始化日志了吗? 是的。我给js和css设置no-cache,然后发现都是200 from server, NOT from cache!!

以上是关于HTML5 应用程序缓存的主要内容,如果未能解决你的问题,请参考以下文章

模拟 HTML5 缓存测试的离线模式

如何正确地使在线/离线 Web 应用程序的 HTML5 缓存清单失效?

用于大查询的 Apps 脚本

Heroku 上带有 SSL 的 WebSockets - Chrome 和 FireFox 中的问题

iPad 上的 HTML5 视频元素不会触发 onclick 或 touchstart 事件?

HTML5中的localStorage啥时候会被清空