這篇並沒有整理完. 提前放出,是因為有朋友關心這部分.我就嘗試拋磚引玉吧. 暫時實在沒精力把 這部分的標准翻譯完整. 放在這里算是督促下自己,盡快寫完吧.
我建議您, 只要簡單看看最后面的總結部分即可.. 因為前面只是我對草案的簡單翻譯 和個人理解.難免有錯漏之處.如果您看的話,建議僅供參考,我無法保證期准確性.
另外,此文再我的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 type是 text/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),分別為open 和 blocking
注:白名單的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請求.