--- title: Firefox 中的離線資源 slug: orphaned/Firefox_中的離線資源 tags: - HTML5 離線 - application cache original_slug: Firefox_中的離線資源 ---
HTML5 提供了 cache 機制,使得網路應用程式能較不受到網路狀態的影響。開發人員可以藉由 Application Cache (AppCache) 的介面來定義哪些資源應當被瀏覽器儲存起來 - 如此一來即使網路斷線使用者依舊可以取得這些資源。同時,應用程式也能正確的運行即使使用者按下了「重新載入」的按鈕。
大抵來說,使用 Application Cache 可以取得下列好處:
啟動 AppCache 的方法很簡單,你只需要在你程式頁面中,html 元素裡指名 manifest 的位置即可,這裡有個簡單範例:
<html manifest="example.appcache">
...
</html>
manifest 指向了一個 cache manifest 的檔案,他指出了在你的應用程式中哪些資源該當被瀏覽器儲存以作為快取。
你應該在每一個你希望瀏覽器替你儲存資源的頁面加上 manifest。瀏覽器不會自作主張的去儲存 manifest 指定以外的資源。事實上,你並不需要列出所有你想要被快取的頁面,瀏覽器會儲存使用者曾經瀏覽過的所有頁面以及你指名的那些資源。
某些瀏覽器 - 例如 FireFox - 會在使用者第一次讀取有使用 Application Cache 的時候提醒他們。提示訊息可能會是這樣:
This website (www.example.com
) is asking to store data on your computer for offline use. [Allow] [Never for This Site] [Not Now]
The term "offline(-enabled) applications" sometimes refers specifically to applications that the user has allowed to use offline capabilities.
Application Cache 的運作是基於讀取 manifest 檔案:
其運作流程如下:
window.applicationCache
物件,其會按照 HTTP cache rules 取回 manifest 檔案。applicationCache.add()
透過 HTTP caching rules 被重新抓取至本地的暫存快取。當一個檔案被抓到本地快取後,瀏覽器會送出 progress 的事件到 applicationCache 物件。如果發生了錯誤,瀏覽器會送出 error 事件並停止更新。在 Chrome 中,使用者可以藉由選擇 preferences 中 Clear browsing data... 清除 application cache 的內容 (此外,也可以造訪 chrome://appcache-internals/ )。Safari 中也有類似的設計,你可以選用 preference 中的 Empty cache 達到一樣的目的 (但 safari 此時可能會要求你重啟瀏覽器)。
而 Firefox 則將這些資料放置在一般的硬碟快取中 (非在 Firefox 的 profile 中):
C:\Users\<username>\AppData\Local\Mozilla\Firefox\Profiles\<salt>.<profile name>\OfflineCache
/Users/<username>/Library/Caches/Firefox/Profiles/<salt>.<profile name>/OfflineCache
使用者可以透過檢查 about:cache 中 Offline cache device 下的資訊來得知目前狀態。
使用者可以清除特定網站的快取藉由 Tools -> Options -> Advanced -> Network -> Offline 中的 "Remove..." 按鈕。補充一下,以下兩個方法無法清除快取
相關資訊亦可參考 clearing the DOM Storage data 。
Application cache 也會有失效的時候。當伺服器端移除了 manifest 後,瀏覽器會自動清除所有在本地端的快取,並且發送 obsoleted 的事件給 applicationCache 物件。這會使得 application cache 的狀態變為
OBSOLETE。
在 manifest 中定義資源的路徑可以分為兩種 - 相對路徑及絕對路徑 (絕對路徑:起始點是 application 所在的那層目錄)。並且,manifest 的 MIME 格式必須為 text/cache-manifest。
Manifest 文件中的資源必須以 URI 格式表示。所有列於 manifest 中的資源,他們的 scheme、host以及 port 都得和 manifest 文件一樣。
這是一個簡單的範例, example.appcache
, 我們假設他屬於 www.example.com
CACHE MANIFEST # v1 - 2011-08-13 # This is a comment. http://www.example.com/index.html http://www.example.com/header.png http://www.example.com/blah/blah
一個 manifest 檔案可以有三種不同的段落 - CACHE
、NETWORK
以及 FALLBACK (容後再敘)。在 example.appcache 中我們並未指定段落名,是以所有資源會被以預設方式解析,也就是「需要被加到快取」(意義上屬於 CACHE 段)。如前所提到,資源可以用相對或絕對路徑表示(例如可以把
http://www.example.com/index.html 改為 index.html)。
在這裡要特別指出被放置在註解中的「v1」字樣。顯然他表達的是版本資訊。但在 manifest 中這樣的表達方式有大用。假設今天 header.png 改變了,你只需要改動版本資訊 (或註解中的內容),則此 manifest 就會被認為有改變而使得瀏覽器重新抓取快取。當然你可以改動檔案中的其他部分,可是改變版本號是比較建議的方式。
CACHE
, NETWORK
, and FALLBACK
在 manifest 中我們可以有三種不同的段落: CACHE
、 NETWORK 以及
FALLBACK。
CACHE:
NETWORK:
FALLBACK:
這三種不同段落可以以任意順序出現在 manifest 中,並且都可出現多次而無次數限制。
這裡我們來看看稍微複雜點的 manifest。他存在於一個虛擬的網站 www.example.com:
CACHE MANIFEST # v1 2011-08-14 # This is another comment index.html cache.html style.css image1.png # Use from network if available NETWORK: network.html # Fallback content FALLBACK: / fallback.html
這個範例中使用了 NETWORK 以及 FALLBACK:
Cache manifest 檔案應該被定義成 text/cache-manifest 的 MIME 格式。而所有被定義成 text/cache-manifest MIME 格式的檔案將被以本章所規範的語法解析。
首先,Cache manifests 必須是一個 UTF-8 格式的文字檔。檔案中可以被嵌入 BOM (Byte-Order Mark)字元,舉例來說,換行會被表示成 「line feed (U+000A
)」、「 carriage return (U+000D
)」或 「carriage return 及 line feed both」。
第二,cache manifest 的第一行必須是「CACHE MANIFEST」字串 (CACHE 和 MANIFEST 中間的那個空白是一個
U+0020 符號),其後可以任意加入 space 或 tab 字符。以這一行來說,其他被加入的字串將會被忽略。
最後,檔案中的剩餘部份是由零至多個下列所述的項目構成:
Section header Description CACHE:
其後內容指出哪些資源需要被加到瀏覽器的快取中 NETWORK:
其後內容指出哪些資源一定得從網路取得 FALLBACK:
其後內容指出資源在有網路連線及斷線時的替代關係
Cache manifest 檔是以上述三種段落來依序判讀,是以每一段落可出現一次以上。甚至你也可以寫出內容為空的段落。
Application cache 總是含有至少一個資源,並以 URI 形式敘述。下面列出資源種類,manifest 中的資源必屬其中。
關於這些資源種類,下面會有更詳細的說明。
Master entries 是一種在他們 {{ HTMLElement("html") }} element 中含有 {{ htmlattrxref("manifest","html") }} attribute 的 HTML 檔。舉例來說,如果我們說我們有一個 http://www.example.com/entry.html 的 HTML 檔,其內容為:
<html manifest="example.appcache"> <h1>Application Cache Example</h1> </html>
如果 entry.html
並未被列在 example.appcache
中,幫妳拜訪 entry.html
時,他就會被加到 application cache 中,並被指明為一個 master entry。
這指出了哪些檔案需要被存到快取中。
這指出了哪些檔案一定得透過網路取得。可以看成是列出了一張線上白名單 (online whitelist),提示了有些東西必須得透過網路向伺服器抓取。這有很多好處,其中一個好處是可以避開些安全漏洞,避免某些認證結果從本地端讀取而造成危險 (如果這個認證結果被竄改的話 ... )。
這裡有個例子,你可以要求執行的腳本一定得透過網路向伺服器抓取:
CACHE MANIFEST NETWORK: /api
Fallback entry 的使用時機在於網路可能斷線。直接看例子,當我們說有個 manifest (http://www.example.com/example.appcache),其檔案內容是:
CACHE MANIFEST FALLBACK: example/bar/ example.html
任何企圖抓取 http://www.example.com/example/bar/
或其子資料夾的請求若是失效,瀏覽器會讀取 example.html
作為替代。
每一個 application cache 都有一個 state,表明目前在瀏覽器端的狀態。共用同一個 manifest URI 的 cache 擁有一樣的狀態。狀態的種類如下:
UNCACHED
IDLE
CHECKING
DOWNLOADING
UPDATEREADY
updateready
的事件。相對於 cached
事件,他的意思是有新版的更新已經在本地,但尚未呼叫 swapCache()函式。
OBSOLETE
你可以經由撰寫 JavaScript 程式來關注是否 manifest 檔有所更新。但未免在你漏失在 Listener 完成註冊之前就完成的事件,務必檢查 window.applicationCache.status。如下所示:
function onUpdateReady() { alert('found new version!'); } window.applicationCache.addEventListener('updateready', onUpdateReady); if(window.applicationCache.status === window.applicationCache.UPDATEREADY) { onUpdateReady(); }
倘若你想手動的去測試 manifest 檔案是否更新,你可以使用 window.applicationCache.update()。
window.applicationCache.swapCache() 達到,但在此刻已經被讀取的資源將不受影響。最好的方式是重新刷新頁面。
ExpiresByType text/cache-manifest "access plus 0 seconds"
{{ CompatibilityTable() }}
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | 4.0 | 3.5 | 10.0 | 10.6 | 4.0 |
Feature | Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
Basic support | 2.1 | {{ CompatUnknown() }} | {{ CompatNo() }} | 11.0 | 3.2 |
附註:先於 3.5 版以前的FireFox 忽略了 manifest 檔案中 NETWORK 以及 FALLBACK 的部分。
{{ HTML5ArticleTOC() }}
{{ languages( { "es": "es/Recursos_offline_en_firefox", "fr": "fr/Ressources_hors_ligne_dans_Firefox", "ja": "ja/Offline_resources_in_Firefox", "pl": "pl/Zasoby_offline_w_Firefoksie", "zh-tw": "zh_tw/Offline_resources_on_Firefox" } ) }}