manifest 和 application cache

这篇并没有整理完. 提前放出,是因为有朋友关心这部分.我就尝试抛砖引玉吧. 暂时实在没精力把 这部分的标准翻译完整. 放在这里算是督促下自己,尽快写完吧.

我建议您, 只要简单看看最后面的总结部分即可..   因为前面只是我对草案的简单翻译 和个人理解.难免有错漏之处.如果您看的话,建议仅供参考,我无法保证期准确性.

另外,此文再我的evernote中.大概是今年2月份左右. 现在可能草案有新的改动.也请留意.

 


 

当前浏览器支持情况:

 

IE10? (至少,似乎 IE10 pp2还不支持. 但是 caniuse上列出的是有支持的.也许是那个win8上的update会有吧?)

Opera10.6+

Safari4.0+

Firefox3.0+

Chrome5+

 

IOS Safari3.2+

android2.1+ 

 

 

 

offline web applications相关标准 : http://www.w3.org/TR/2011/WD-html5-20110525/offline.html 

manifest文件相关标准 : http://www.w3.org/TR/2011/WD-html5-20110525/iana.html#text-cache-manifest

manifest文件解析流程: http://www.w3.org/html/ig/zh/wiki/HTML5/offline#parse-a-manifest

application cache selection algorithm : http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#concept-appcache-init

Changes to the networking model : http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#changesToNetworkingModel

 

 

 

Offline Web applications

 

 

关于manifest.

首先 manifest 的 contentType = text/cache-manifest

然后,其扩展名,建议为 "appcache"

 

Type name : text

Subtype name : cache-manifest

Required parameters : No parameters

Optional parameters : No parameters

Encoding considerations : Always UTF-8.

 

隐私相关:manifests 设计上,没有什么直接的敏感信息问题.除非,manifests文件自身包含了敏感信息.

另外,这东西是专门应用于 Web browsers的.

 

note : (此部分并非标准,而是建议)

     1. 标准鼓励,缓存包含manifest清单的页面,所以实际上,即使我们不显示的把包含manifest的页面,列在manifest缓存清单中,这个页面也会被缓存的.

     2. HTTP相关的缓存头域 以及 https的缓存页面限制,将被manifest所无视. 所以在用户代理 更新页面之前,它是不会过期的. 也就是说,即使是一个HTTPS的东西.也可以脱机工作.

 

 

简单demo : 

<!DOCTYPE HTML>

<html manifest="clock.appcache">

<head>

  <title>Clock</title>

  <script src="clock.js"></script>

  <link rel="stylesheet" href="clock.css">

</head>

<body>

  <p>The time is: <output id="clock"></output></p>

</body>

</html>

 

 

 

Manifest 的语法:

 

CACHE MANIFEST

# 上面这行是必须的

 

# 这是一行注释

# 在这个文件中的任何地方都可以添加

# 它们全部都会被忽略

  # 在注释之前可以有空格

  # 但必须是在单行前

 

# 空行也会被忽略

 

# 这些列在最开始的文件都是需要被缓存的

# 或者是那些列在"CACHE:"里的, "CACHE"头必须写在这些文件之前,如同

# 下面写好的那样

CACHE:

images/sound-icon.png

images/background.png

# 注意,每个文件必须单独一行

 

# 在线白名单中出现的这个文件,它不会被缓存,并且,

# 对该文件的引用,将绕过缓存,总是会

# 从网络中获取目标(或在用户离线时,尝试从网路上获取)

NETWORK:

comm.cgi

 

 

 

 

我们也可以书写成这样:

CACHE MANIFEST

NETWORK:

comm.cgi

CACHE:

style/default.css

images/sound-icon.png

images/background.png

 

 

 

离线应用程序缓存清单可以使用相对路径或绝对URL地址:

CACHE MANIFEST

 

/main/home

/main/app.js

/settings/home

/settings/app.js

http://img.example.com/logo.png

http://img.example.com/check.png

http://img.example.com/cross.png

 

 

 

     下面的清单定义了一个捕捉所有错误(应该指http错误,导致无法正常显示)的页面,它会在用户离线时被显示出来。它同时也指定在线白名单通配符标记(online whitelist wildcard flag)为开启(open)状态(下面在相关概念介绍部分会有提及),即,在访问其他站点资源的时候不会被阻止(blocked,是指访问其他站点资源,不受manifest影响.)。(相同站点的资源已经不会被阻止了,因为有捕捉所有的备用命名空间的通配符)只要站点上所有的页面引用了这个缓存清单,这些页面,都将全部从本地缓存中取得,就如同它们实际上被读取一样,随后,那些被命中的同名页面,会立即从缓存中加载,直到缓存清单发生了改变,否则,那些页面将不再从服务端读取。当缓存清单发生改变时,所有的文件都将被重新下载。因为子资源并没有别列在清单的明示域,所以,子资源NETWORK的通配符匹配了,这时候,如css样式表,图片等等,无论如何,只能通过常规的HTTP缓存语义进行缓存。

CACHE MANIFEST

FALLBACK:

/ /offline.html

NETWORK:

*

 

 

 

应用程序缓存下载过程(application cache download process)步骤:

参考地址:http://www.w3.org/html/ig/zh/wiki/HTML5/offline#application-cache-download-process

 

1. 可选,等待,直到通过用户授权开始应用程序缓存下载过程(application cache download process),且user agent确认网络可用。这可能包括在用户明确该站点选用缓存前,或者需要向用户询问授权前,什么都不做。在这时,算法规则                    永远不会被执行。(当前步骤特意为那些运行在有空间限制或隐私高度敏感的user agent环境而设计)

 

2. 自动的, 为了避免竟态条件(race conditions),执行下列子步骤:

     (1). 选择合适的子步骤:

               .如果这些步骤是以一个绝对URL,来调用,用于识别一个manifest则:

                    令 manifest URL 为这个绝对URL.

                    如果没有一个用manifest URL,作为标识的application cache group,则创建一个新的application cache group.并以 manifest作为其标识.

                    初始化时,这个application cache并没有属于它的application cache, 但会在接下来的算法中创建.

               .如果这些步骤是以一个application cache group调用的则:

                    令manifest URL为application cache group所对应的manifest的绝对URL标识,以用于更新.

                    如果application cache group被标为废弃状态.则终止这次应用程序缓存的下载过程. application cache group被标为废弃,会发生在下载过程第一步,在等待manifest下载时,发现缓存清单返回404或410的情况.

     (2). 令cache group为 application cache group并以 manifest URL 为其标识.

     (3). 如果这些步骤是以一个主体资源调用的, 则把这个资源与其对应的Document一并添加到cache group的待定主体项列表中去.

     (4). 如果这些步骤是以一个cache host调用,并且cache group的status的值为checking 或downloading(这里不是笔误,整个8个子步骤是为了避免静态条件的发生,是1 by 1的查看步骤. 所以隐含的意思是,checking是必须要先触发的.如果status是downloading,又没触发过checking事件,则就要触发一次checking,即使当前的status是downloading也要如此. 然后再进入步骤5.),则发起一个post-load (参考:http://www.w3.org/TR/2011/WD-html5-20110525/webappapis.html#task-queue部分,post-load task.这里指事件队列. 对于事件来说,异步的在一个具体的事件源对象上,派发一个事件,就是一个任务.那么 此时的task queue 就是一个异步事件队列. 类似的还有 HTML parsing 队列等等.)任务队列.并,在cache host所属的ApplicationCache(对象)上触发一个可取消的checking事件.如果用户代理实现了所谓显示缓存过程(shows caching progress,这东西用户代理可以选择性实现,并非标准硬性规定.即给用户显示资源的缓存过程、进度信息.),则该事件的默认行为,必须是,用户代理,通过某种方式提示用户,当前正在检测是否可以进行应用资源的下载.

     (5). 如果这些步骤是以一个cache host调用,并且cache group的status的值为downloading,则发起一个post-load 任务队列.并,在cache host所属的ApplicationCache(对象)上触发一个可取消的downloading事件.如果用户代理实现了所谓显示缓存过程,则该事件的默认行为,必须是,用户代理.通过某种方式提示用户,正在进行应用资源的下载.

     (6). 如果一个application cache 要进行update的同时, 其status是 checking 或downloading,则就要终止当前的application cache download process. 

     (7). 把cache group 的status设置为 checking状态.

     (8). 为 cache group中每个 cache host相关联的application cache,发起一个post-load 任务队列. 并在cache host对应的ApplicationCache(指window.applicationCache object)上触发一个,可取消的,叫做 checking 的简单事件(simple event,指直接继承自Event接口的,除非另有说明,否则默认没有冒泡行为,也不可取消的事件类型.)如果用户代理实现了所谓显示缓存过程,则该事件的默认行为,必须是,用户代理.通过某种方式提示用户,正在检测应用资源的是否可更新.

     ps: 个人理解2步骤中的8个子步骤,所谓避免静态条件,就是指一个application cache group中多个application cache 同时各自更新cache, 网络资源竞争.等等现象.其实我们并不需要太关系具体细节.

     

     Note: 剩余的步骤全都异步进行.

     如果cache group 已经具备一个application cache,则进入尝试更新流程(upgrade attempt), 否则进入尝试缓存流程(cache attempt)

 

3. 如果这是在做 cache attempt(缓存尝试),那么此算法就一定是以一个 cache host调用的. 则,发起一个post -load 任务队列,在cache host对应的ApplicationCache上,触发名为 checking ,且可被取消的简单事件.如果用户代理实现了所谓shows caching progress则该事件的默认行为,必须是用户代理.通过某种方式提示用户,正在检测应用资源的是否可更新.

 

4. 获取manifest: 以同步标识设置的方式通过manifest URL 获取manifest.

    

    如果manifest文件的 MIME typetext/cache-manifest. 则按照manifest解析规则来进行解析(参考:http://www.w3.org/TR/2011/WD-html5-20110525/offline.html#parse-a-manifest).并获取明示项备用项备用名称空间在线白名单项、以及在线白名单通配符标记的值.

 

5. 如果因404或401响应或其他类似的原因导致,获取manifest失败,则执行下面的子步骤:

     (1). 把 cache group标为废弃. 如果这时候,该cache group中,没有一个Document与一个application cache相关联,则这个cache group就没有任何存在的价值了.

     (2). 令task list 为一个空的任务列表.

     (3). 在cache group中,每一个关联了一个application cahe的cache host所对应的ApplicationCache对象上触发一个,可取消的、名为 obsolete 的简单事件. 并把这个事件添加到 task list中去. 如果用户代理实现了所谓shows caching progress则该事件的默认行为,必须是用户代理.通过某种方式提示用户,应用程序在离线状态下,将不可用.

     (4). 在cache group的待定主体项清单中的每一项的Document所对应的ApplicationCache对象上,创建一个任务并触发一个 可取消的,名为 error(并不是 obsolete)的简单事件.如果用户代理实现了所谓shows caching progress则该事件的默认行为,必须是用户代理.通过某种方式提示用户,用户代理为应用离线工作所作的保存(缓存)失败了.

     (5). 如果cache group的某个 application cache的 completeness flag为 incomplete(即某个application cache的完整性标记为未完成),则抛弃之.

     (6).移除可能存在的,所有表示该cache正在更新的 ui信息.

     (7). 令cache group的status为"idle" (空闲状态).

     (8). 为任务列表中的每个人物,发起一个post-load任务队列.

     (9). 取消应用程序缓存下载(application cache download)过程.

 

6. 另外,如果因其他原因导致获取manifest失败(举例来说,服务器返回了其他4xx,5xx响应,或类似的事情,又或者是DNS错误.或连接超时.又或者检测魔法签名时,解析manifests失败.).或者服务器返回一个重定向,或者manifest的MIME type不是text/cache-manifest .则进入缓存失败步骤(cache failure steps,在后面解释.):

 

 

7. 如果处于尝试更新流程,并且新下载的manifest文件.与cachegroup中最新的application cache的manifest,完全相同,或者下载文件时服务器端返回"304 not modified" 或其他等价的结果.则执行下面的子步骤:

     1. 令 cache 为 cache group 中最新的application cache.

     2. 令 task list 为一个 空的任务列表.

     3.  未完成... 待续.

 

 

 

     

 

 

 

 

 

 

ApplicationCache对象:

      本章节属于非规范性内容.

    

     当用户访问一个声明了manifest的页面时, 浏览器会尝试更新缓存. 通过获取一份manifest文件的副本来实现校验. 如果manifest相对上一次读取该文件,有变化,则就要更新全部清单中列出的资源.

     在这个过程中,在ApplicationCache对象上会触发一系列的事件,来使脚本保持缓存更新的状态,以便用户可以得到适当地通知。这些事件如下:

     

             

 

     ApplicationCache对象相关事件:

事件名

接口

被触发的时间

下一个可能的事件

checking

Event

当用户代理校验是否需要更新,或首次尝试下载manifest文件的时候,此事件,总是ApplicationCache对象相关事件序列中,第一个发生的.

noupdate, downloading, obsolete , error

noupdate

Event

manifest没有任何改变,确认不需要更新的时候.

序列中最后一个事件.

downloading

Event

用户代理找到一个更新(针对cache group),并获取该资源,或首次下载缓存清单中的全部资源的时候.

progress, error, cached, updateready

progress

ProgressEvent

用户代理下载缓存清单中所列出的资源时发生.(每个resource被下载都会触发一次该事件.)

progress, error, cached, updateready

cached

Event

用户代理下载某资源结束并缓存该资源后发生.

序列中最后一个事件.

updateready

Event

缓存清单中的资源被重新下载后,并且script可以调用 swapCache()方法去替换缓存时

序列中最后一个事件.

obsolete

Event

manifest文件 404 或 410时, 缓存会被删除.然后触发此事件.

序列中最后一个事件.

error

Event

1. mainfest 404 或410时.

2. manifest没有改变,但是无法正确定位并下载引入manifest文件的页面的时候.

3. 获取某个在缓存清单中的资源时,发生某些严重的错误.

4. 当缓存(猜测指的是manifest,而不是指清单上的资源)更新时,manifest发生了变化..

序列中最后一个事件.

 

 

对应4: 用户代理会随时尝试再次获取manifest文件.

 

 

ApplicationCache对象属性

          .status : 

               0 :  UNCACHED (代表未缓存)

               1 :  IDLE (表示空闲状态)

               2 :  CHECKING(表示增在检测缓存新鲜度)

               4 :  UPDAEREADY(空闲+ !obsolete + application cache不能为刚刚更新的.)

                    

 

 

 

     ApplicationCache对象方法

          .update()

          主动更新所有缓存清单中列出的缓存资源.

          

          .swapCache()方法(标准地址:http://www.w3.org/TR/2011/WD-html5-20110525/offline.html#dom-appcache-swapcache)

          简单来说就是,当updateready后,我们调用这个方法,就达到了用新文件替换老缓存文件的目的.

 

          .abort()方法. 2012年1月,草案更新,追加的方法目前似乎没有浏览器实现.. 参考: http://dev.w3.org/html5/spec/Overview.html#applicationcache

           原文只有一段描述:

          If the abort() method is invoked, the user agent must send a signal to the current application cache download process for the application cache with which theApplicationCache object's cache host is associated, if any. If there is no such application cache, or if does not have a current application cache download process, then do nothing.

 

          

 

 

 

 

          

 

相关概念: 

     . application cache 由一组缓存资源组成的集合,他可能包括下面这些东西: (参考地址:http://www.w3.org/html/ig/zh/wiki/HTML5/offline#application-cache)

               .一个或多个资源,通过url进行识别,可以分为下面几种类别:

                         主体项(Master entries)

                              注:这些文档被添加到缓存中是因为浏览环境上下文(browsing context)被导航(navigated)到那些文档中(这说的就是引入了manifest的页面.)

          

                         .缓存清单(Manifest)

                              注:这是与在主体项html元素的manifest属性中给出的URL相对应的资源。它会在application cache对象的download process过程中被取出并进行处理。所有的主体项(master entries)必须与与manifest文件同源(same origin)

 

                         .明示项(Explicit entries)

                              注:这些都是在缓存清单的明示区域(explicit section)中列出的资源

     

                         .备用项(Fallback entries)

                              注:这些都是在缓存清单的备用区域(fallback section)中列出的资源

                         

               .零个或多个备用名称空间(fallback namespaces)   的URL

                    注:与备用项存在映射关系.  备用项就是备用名称空间的备用项,也就是说备用名称空间所代表的url,或其通配符所匹配的那些url,一但访问不能,就要以备用项url作为后备使用.

 

               .零个或多个在线白名单名称空间(online whitelist namespaces)的URL

                    注:在白名单区域出现的url,或被其通配符所匹配的url,都不会从离线应用程序缓存加载资源,而总是尝试从网络中获取(HTTP Cache是有效的.).

 

               .在线白名单通配符标记(online whitelist wildcard flag),分别为openblocking

                    注:白名单的open状态(以通配符"*"作为首个token的白名单,则进入open状态,表示匹配所有URL,如果*不作为首个token出现,会被忽略.)表示, 所有被在线白名单名称空间 ,所匹配的url,如果没有显示的出现在CACHE项中,则都视为 该资源存在于白名单中(因为进入open状态,此时这些资源,都是遵守HTTP缓存头域相关缓存策略的.). blocking状态(即白名单内容首个token不是"*"的状态.则此时白名单中是列出具体的url,或者前缀匹配的表达式的.被匹配的部分则,同open状态匹配一样.可以根据HTTP缓存头域进行正常的访问.),则表示,manifest中没有显式出现过(也不被各类通配符所匹配的)url(自然也包括没有被白名单明确匹配的URL), 会被manifest无效处理.(无效处理,浏览器的实现就是获取不能.无法下载.)

                    参考:http://www.w3.org/TR/2011/WD-html5-20110405/offline.html#changesToNetworkingModel 中的描述.会更明确的说明,无效处理,指的就是下载不能.

 

                   (参考:如果某个资源文件被列在了明示区域(explicit section)或是备用区域(fallback section)中的一个备用项目实体(fallback entry),那么,该资源也可以从缓存中读取,不论它是否匹配到了其他的备用命名空间(fallback namespaces)或在线白名单命名空间(online whitelist namespaces)的项目实体.)

 

               .应用程序缓存的完整性标记(application cache completeness flag),状态分为complete和incomplete

 

 

               .应用程序缓存组(application cache group) ,即是借助manifest的url来进行分组一组组的应用程序缓存(application cache).(也就是说,具有相同 manifest url但是cache host不同的 application cache被放置在一个cache group里)

                         . 一组application cache,后出现的是更则是新鲜的,也就是说,一组application cache.是按时间顺序排序的

 

                         . 在application cache group中,只有最新的application cache的完整性标记(completeness flag)值为“不完整”的(incomplete);其他的都为“完整的”(complete)

 

                         . 每个application cache group 都有一个更新状态(update status),其值为以下其中一种:idle, checking, downloading

 

                         . 符合的应用程序缓存(relevant application cache)是在该缓存组(group)中最新的(newest)且被标记为“已完成”(complete)的那个application cache。

 

                         . 每个application cache group都有一个待定的主体项清单(list of pending master entries).清单中的每一项,都由一个资源以及对应的一个Document对象所组成. 

                           它们用于在应用缓存下载过程中确认新的主体项是否被缓存.  

 

                         .application cache group可以被标记为作废的(obsolete),即在检查已存在的application cache group时,必须忽略它们.

 

                         .application cache group中的诸多application cache,的清单都是相同的,而用户代理要从relevant application cache中选出,用户最可能需要的那一个,就要考虑下面这些因素:

                                   1.哪个application cache是最近被更新的

                                   2.哪些应用程序缓存是用来列出那些用户决定需要检查的新资源,且

                                   3.哪些应用程序缓存是用户偏好的

                         

 

               .缓存宿主(cache host)是一个Document对象,或一个SharedWorkerGlobalScope对象(参考:http://dev.w3.org/html5/workers/#shared-workers-introduction).他们可以和一个application cache关联.

                         Document对象在初始时并未与application cache关联,而是在一个较早的页面加载过程中,当进到in the parser过程,在navigation这块,由cache selection引发,从而使得它们进行关联。

                              .in the parser :http://www.w3.org/TR/2011/WD-html5-20110525/tree-construction.html#parser-appcache

                                   简单的说,这里是指html parse的过程中,遇到html manifest =xxx的部分,就使用这个xxx 的绝对url,进行 所谓缓存算法选择流程.(缓存算法选择,会在后面解释.)

 

                              .navigation :http://www.w3.org/TR/2011/WD-html5-20110525/history.html#navigate

                                   navigation是针对资源的导航过程.大概步骤有20步.很繁杂.

                         ps: cache host ,说白了就是,  window.applicationCache 中 window所对应的当前页这个Document. 也就是说 Document要对应一个ApplicationCache对象用于控制,一组application cache,即 application cache group


 

 

 

 


 

总结:

. 引入 manifest方式为 :  <html manifest="name.appcache">

. manifest的加载是晚于页面其他资源的.

. manifest的contentType应为 : text/cache-manifest

. 建议其扩展名为 : appcache

. manifest文件本质是一个,要采用UTF-8编码方式编码的文本文件.

. 引入manifest的页面,即使没有被列入缓存清单中,仍然会被用户代理缓存.

. manifest文件从标准角度来说,是不能直接从缓存读取的.即使像上一条说的,你明确的把manifest放入另一个清单中.至少也是服务器尝试返回304.再去读缓存.(注1)

. 在线的情况下,用户代理每次访问页面,都会去读一次manifest.如果发现其改变, 则重新加载全部清单中的资源(注2).

. 对于浏览器来说,manifest的加载是要晚于其他资源的. 这就导致check manifest的过程是滞后的.发现manifest改变.所有浏览器的实现都是紧随这做静默更新资源.以保证下次pv,应用到更新.

. manifest文件必须与引入它的页面同源.

. 如果manifest文件是一个https或其他加密协议资源,则其清单中明示项(explicit section)的资源都必须和manifest同源.

. 备用项和备用名称空间,必须与当前的manifest同源.

. 备用项如果发生命中,则也会被缓存.

. 明示项和备用项优先级高于白名单.

. 白名单使用通配符"*". 则会进入白名单的open状态. 这种状态下.所有不在相关Cache区域出现的url都默认使用HTTP相关缓存头策略.

. 白名单使用具体的前缀匹配或更具体的URL,则都属于blocking状态.这种状态下,白名单所匹配的,非Cache区域出现的URL,与open的*匹配的结果一致,但是不在白名单中,又不在整个manifest的资源,会block.也就是访问,加载不能.

. manifest中的url ,必须与manifest使用相同的协议.

. 一个manifest的明示项中可以包含另一个manifest.(但这种设计,我认为很2.)

. manifest中的url,不应有"#" 锚点部分出现(比如 abc.htm#1,如果出现#,则 #以及后面部分,会被丢弃.)

. 建议使用<!DOCTYPE html> DTD, 因为据说,某些浏览器会因为,进入非标准模式,而无视manifest.

     (我本人没有实测,但我个人猜测,如果有这样一款浏览器,那么它很可能就是IE10. 因为IE10进入兼容模式,很多html5草案的API都使用不能.比如performance API)

. 被清单缓存的资源,是无视http cache 相关 头域, 或其是否是https资源的.

. 相同备用名称空间,不能重复出现在 备用区域中.

. 不应有相包含的备用名称空间出现在备用区域中(因为前缀匹配的原因.出现包含,显然是多余的,如果真有一个URL同时匹配两个通配符.那么就以更长的那个为准.).

. 备用名称空间 和 白名单名称空间 都使用前缀匹配模式.即支持通配符匹配模式.(可以放心的是 //www.a.com/abc 是不匹配 //www.a.com/ab的,因为//www.a.com/ab 实际上是//www.a.com/ab/)

. 前缀匹配对端口的匹配是宽松的.如abc.com:80/a.png 就会被 abc.com/所匹配.

. 在写相对路径的时候 不是相对 引入它的html  而是相对 manifest文件所在目录的

. 一但manifest检测,需要更新,导致所有cache资源更新。其中manifest会再次加载一次.(所以给所有缓存资源配置合理的304机制.是十分有必要的.)

. 一组不同的页面引入相同的manifest文件时,这组页面的即构构成一个group.并已document作为标识,来区分他们.其中任何一个的manifest或资源更新,甚至是检测都会触发其他页面的applicationCache的相应事件.

. applicationCache.update(), 只会立刻检测manifest文件,而不会更新相应资源.并且会遵守304相关http缓存头.

. a,b两个页面,引入相同资源,但a有使用manifest,而b没有.那么,即使a页面缓存了资源.b页面也不会有效.而且b页面强制更新了资源.a页面的缓存也不会因为b的更新,而更新.

. a页面引入manifest,缓存的资源, 在浏览器地址栏中直接访问,则也命中offline application的缓存.刷新也如此.至少chrome,FF都是如此实现的.

. a,b两个页面,分别引入A,B两个manifest文件,且分别缓存相同的一个资源R,则 如果此时更新R,然后更新B.则.b刷新后重新获取资源R,但是a的R资源缓存副本是不会被更新的.

. a,b两个页面,引用同一份manifest A. 则更新A,更新R,刷新b, b对应的R资源更新后,a的R资源副本也会随之更新. 这就是cache group的机制.因为a和b对应的application cache,同属于同一个application cache group.

 

. 建议为manifest文件配置304相关 头域时,也配置expires和cache-control : max-age.因为chrome,safari,以及android,只有304相关头域,而没有expires 或 max-age时,不会有304,而只会是200, opera则无视一切http cache头域.总是200.

  (浏览器的实现都有问题,webkit的问题是,没有遵守http协议.因为304相关头域是足矣使浏览器是具备资源副本,并做握手的. 而opera则完全无视http缓存头域.更加不靠谱. (IE10 pp2,FF系列.不方便测试))

 


 

  

注1: FF的实现有bug.他有自己的时间管理,在短时间内重复请求一个manifest,FF会有直接从cache中读取的情况出现.即使,我们主动使用applicationCache.update().而 FF9+开始,这个所谓的短时间,被延长了很久,至少我个人没有实测出到底要多久.因为同样一个manifest,有时候他就要我等很久,有时候很短暂(暂时没有找出具体规律,至少和Expires,max-age等头域无关.). 这是不符合规范的做法.规范中唯一允许,不经验证,直接从cache读取manifest的就是,如在地址栏直接get manifest或类似的的情况.

 

注2 : 所谓重新加载, 是依然遵守http 的缓存相关头域的, android webkit browser, chrome ,FF6- 等. 但是FF7+ 开始有了优化, 当缓存资源的http Expires 等相关缓存头域显示该资源没有过期时,FF6+依然会去本地缓存去的资源. 而不像其他浏览器,则会尝试带着304相关头域发起http请求.

posted @ 2012-11-23 10:35 Franky 阅读(...) 评论(...) 编辑 收藏