正巧看到在送書,因而乎找了找本身博客上記錄過的一些東西來及其無恥的蹭書了~~~javascript
小廣告:更多內容能夠看個人博客css
以前在segmentfault上刷問題看到一個關於manifest的問題,很好奇就研究了一下application cache。Application Cache是HTML5的新特性,容許瀏覽器在本地存儲頁面所須要的資源,使得頁面離線也能夠訪問。以前研究的目的是爲了在博客中使用,將一些不須要改動的CSS、JavaScript、圖片文件離線緩存,這樣加載速度必然飛起,但願能用在博客上,可是失敗了,但仍是記錄一下學到的知識html
首先須要在服務器上創建一個文件,裏面的內容肯定了哪些文件須要緩存,哪些文件不須要,若是資源沒法訪問會使用什麼頁面等java
這個文件通常爲.appcache
類型,稱爲緩存清單(cache manifest)文件,一個完整的緩存清單文件以下:chrome
CACHE MANIFEST # version xx.xx.xx CACHE: needBeCached.png needBeCached2.js NETWORK: notNeedBeCached.html notNeedBeCached2.css FALLBACK: / 404.html
能夠看到,文件的頭部信息CACHE MANIFEST
用來標註這個文件是緩存清單文件,其後通常狀況下(最好是)跟着一行標明版本的註釋,這行註釋很是重要,將在後面文件加載部分詳細介紹這行註釋的重要性segmentfault
除了頭部信息,這個緩存清單文件分爲幾部分,第一部分爲CACHE部分:瀏覽器
CACHE: needBeCached.png needBeCached2.js
這一部分標註了哪些資源文件須要被緩存能夠列出多個緩存
若是有路徑,如須要緩存blog下的blog.css文件,能夠寫成blog/blog.css
。服務器
另外CACHE:
能夠被省略,讓須要緩存的資源文件直接跟在註釋以後網絡
第二部分爲NETWORK部分:
NETWORK: notNeedBeCached.html notNeedBeCached2.css
這一部分定義了哪些文件不須要緩存,這些文件須要與服務器鏈接
與CACHE同樣,能夠定義多個資源,而若是直接輸入一個文件夾路徑,也是合法的,好比/blog
這樣,blog文件夾下的全部文件都不會被緩存
可使用通配符來,如除了上面CACHE中定義的資源,其餘都必須與服務器鏈接:
NETWORK: *
須要注意一點是,載有這個manifest文件的HTML文檔將必定會緩存,這個會在後面再次提到
第三部分爲FALLBACK部分:
FALLBACK: / 404.html
這一部分指定了一個後備頁面,當資源沒法訪問時,瀏覽器會使用該頁面
一樣能夠定義多條記錄,每條記錄列出兩個URI,一個表示資源,一個表示後備頁面。須要注意的是兩個資源文件都須要使用相對路徑切與manifest文件同源
一樣可使用通配符
manifest文件能夠保存在服務器上,保存爲.appcache
後綴,但必須與應用自己同源。在HTML文檔中,能夠指定清單文件的相對路徑和絕對URL。須要注意的是,manifest文件的MIME類型必須是text/cache-manifest
須要在HTML文檔中引入manifest文件,可使用相似以下代碼:
<!doctype html> <html manifest="manifest.appcache"> ... </html>
這樣,HTML文檔加載後,就會根據manifest.appcache的內容來緩存資源文件,在下次訪問相同頁面的時候,會直接使用緩存的資源文件來進行加速
在第一次訪問時,瀏覽器加載完HTML文檔後,會查看其是否有引入manifest文件。若引入,則加載manifest文件,而後根據manifest的文件內容進行資源的緩存,並緩存當前文檔
以後訪問,瀏覽器首先會查看manifest文件是否被修改(不管是內容仍是註釋),若是被修改,將當作第一次訪問,從新根據manifest文件內容進行緩存
若是應用緩存存在,且manifest沒有被修改,瀏覽器直接從緩存中加載文檔(注意:加載文檔)和資源,不會訪問網絡(注意:不管聯網與否,都不會訪問網絡)
在緩存多個資源文件時,瀏覽器下載資源文件會先放在一個臨時的緩存中,若是有任何一個資源文件下載失敗,瀏覽器將中止其餘緩存資源的下載,並清除臨時緩存。若是全部資源文件都被成功下載,瀏覽器將會把這些資源文件以及引用manifest文件的HTML文檔移動到永久離線緩存中
text/cache-manifest
,若是使用 Apache,須要修改.htaccess文件。IE下默認application/octet-stream,須要在服務器指定網上傳言避開一號坑的方法是使用iframe來指定須要緩存的資源,而避開HTML文檔的緩存。具體作法是在HTML中嵌入一個iframe,iframe中的頁面的HTML標籤包含manifest屬性引用manifest文件,裏面定義了須要緩存的文件。這樣就會只緩存iframe中的HTML文檔,而持續更新主頁面:
<!doctype html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>主頁面</title> <link rel="stylesheet" href="css/style.css"> <script src="js/javascript.js"></script> </head> <body> <iframe src="cache.html"></iframe> </body> </html>
能夠看到,主頁面的html標籤中,並無引入manifest文件。只是在其中加載了一個iframe,而這個iframe所加載的頁面文檔以下:
<!DOCTYPE html> <html manifest="manifest.appcache"> <head> <meta charset=utf-8 /> <title>緩存頁面</title> </head> <body> </body> </html>
緩存頁面中引入了manifest文件,這樣瀏覽器就會緩存manifest文件中定義的資源列表,好比這裏manifest文件的內容以下:
CACHE MANIFEST # VERSION 1.0 CACHE: css/someStyle.css js/someJavaScript.js NETWORK: *
在chrome中運行,能夠在命令行中看到以下效果:
Creating Application Cache with manifest http://localhost:8000/manifest.appcache Application Cache Checking event Application Cache Downloading event Application Cache Progress event (0 of 2) http://localhost:8000/css/someStyle.css Application Cache Progress event (1 of 2) http://localhost:8000/js/someJavaScript.js Application Cache Progress event (2 of 2) Application Cache Cached event
瀏覽器緩存了manifest文件中定義的資源文件,其實同時還緩存了iframe中的緩存頁面的文檔,但不會緩存主頁面,修改一下主頁面,並按F5刷新
Document was loaded from Application Cache with manifest http://localhost:8000/manifest.appcache Application Cache Checking event Application Cache NoUpdate event
能夠看到主頁面被更新了,可是someStyle.css和someJavaScript.js文件依舊從網絡上加載了,而沒有從cache中加載。打開chrome的chrome://appcache-internals/
能夠看到,裏面cache.html、someStyle.css、someJavaScript.js確實被緩存了,去掉NETWORK段,結果也是同樣
Flags URL Size (headers and data) Master, http://localhost:8000/cache.html 388 B Explicit, http://localhost:8000/css/someStyle.css 228 B Explicit, http://localhost:8000/js/someJavaScript.js 244 B Manifest, http://localhost:8000/manifest.appcache 316 B
在firefox、opera上測試也是同樣,雖然被緩存了,但依舊會從網絡上加載,而iframe的解答方法也是2011~2012年左右提出的,後來就沒有相關文章了,估計已經完全失效了
Application主要是爲了構建離線緩存,使得頁面在離線模式下也能瀏覽。這比較適合一些頁面上的應用以及靜態的不常常變動的頁面。其會緩存載體頁面也是因爲其機制。若是上面iframe機制實現有錯誤,或是有其餘方法只緩存資源不緩存HTML文檔,請聯繫我