瀏覽器緩存主要有兩類
緩存協商:Last-midified ,Etag
徹底緩存:cache-control,Expires

緩存協商的意思是需要去服務器端詢問頁面有沒有修改過,沒有修改過則返回304直接使用緩存內容,否則返回新內容
協商步驟:
1、服務器發送帶Last-midified:GMTtime 頭的http response
2、瀏覽器下次請求時帶上if-modified-since:GMTtime http 請求頭
3、服務端用本地Last-midified時間與if-modified-since比較,計算瀏覽器數據是否過期並發送響應
Etag的工作原理與Last-midified類似,不同點在於Etag的值是用戶可自定義的

徹底緩存的意思是在緩存失效之前不再需要跟服務器交互
常用的是Expires,Expires的值是一個絕對時間,由服務器產生 這兒存在一個問題,就是服務器的時間可能給客戶端的時間不一致導致緩存時間的偏差
要解決這個問題就要使用cache-control,它保存的是一個相對瀏覽器的時間
如果同時存在cache-control和Expires怎么辦呢? 瀏覽器總是優先使用cache-control,如果沒有cache-control才考慮Expires

expire:
如果apache開啟了expire模塊, 當瀏覽器發送該資源請求的時候, apache返回資源的同時,會返回一個名為expire的http頭,expire頭的內容是一個時間值, 這一個值就是資源在本地的過期時間, 這個值會存在本地.
也就是說,在本地緩存階段,在本地找到了一個對應的資源值,而且當前時間還沒超過資源的過期時間, 那么就直接使用這一個資源,不會發送http請求.
cache-control:
cache-control是http協議中常用的頭部之一,顧名思義, 他是負責控制頁面的緩存機制,如果該頭部指示緩存, 緩存的內容也會存在本地, 操作流程和expire相似,但也有不同的地方, cache-control有更多的選項, 而且也有更多的處理方式.
if-modified-since 和 last-modified:
當apache接收到一個資源請求(假設是用戶是第一次訪問,沒有任何緩存), 服務器返回資源的同時,還會發送一個last-modified的http響應頭, last-modified響應頭的內容值是該資源在服務器上最后修改的時間.瀏覽器接受到這個http頭后,會
把其內容值和資源同時保存起來.
當用戶第二發送資源請求(假設這里expire沒有生效或者已經過期), 瀏覽器在本地找到了一個相同的資源,但是不能確定該資源是否和服務器上的一樣(有可能在兩次訪問期間,服務器上的資源已經被修改過),此時瀏覽器發送請求的時候,請求頭內會
附帶一個if-modified-since的請求頭, 這個頭部的內容就是上一次last-modified返回的值, 服務器把這個頭的值和請求資源的最后修改時間對比,如果兩個值相同,則認為資源沒有修改,將會返回304,讓瀏覽器使用本地資源.否則服務器將返回資源,而且
返回200狀態
if-none-match 和 etag:
其實這兩個頭部和if-modified-since, last-modified的工作原理是一樣的, if-none-match作為請求頭, etag作為響應頭.既然工作原理一樣, 為什么etag這對頭部會出現呢?
原因在於, last-modified請求頭的內容是以文件最后修改的時間作為對比的,但是unix系統里面, 文件修改的時間只保存到了秒. 如果某些應用內存在1秒內對文件做了多次修改,這樣last-modified是不能完成比較功能的.所以要引入一個新的機制(原因可能不止這一個);
etag的值一般由3個數值組成,資源的inode值, 最后修改時間, 資源大小,以16進制組成一個字符串, 例如:1a-182b-10f; 但這個格式不是固定的, 只要保證該值的唯一性,但不限格式.
靜態資源的更新:張雲龍老師的blog寫的很好移步這里
html5離線存儲
步驟:
1、配置apache讓apache支持manifest文件
2、創建manifest文件test.manifest
1 CACHE MANIFEST # wanz app v1 2 # 指明緩存入口(指明需要緩存的文件) 3 CACHE: index.html style.css images/logo.png scripts/main.js # 以下資源必須在線訪問 4 NETWORK: login.php 5 # 如果index.php無法訪問則用404.html代替 6 FALLBACK: /index.php /404.html
3、關聯manifest文件到html文檔
1 <html manifest="test.manifest"> ... </html>
注意:#是用來注釋一行的,但它還有一個小作用,web應用的緩存只有在manifest文件被修改的情況下才會被更新,所以如果你只是修改了被緩存的文件,那么用戶本地的緩存還是不會被更新的,但是你可以通過修改manifest文件來告訴瀏覽器需要更新緩存了。利用這點,你可以像上面的例子中那樣,寫一句這樣的注釋一個文件版本:
# wanz app v1
優點:你可以很明確的了解離線web應用的版本
通過簡單的修改這個版本號就可以輕易的通知瀏覽器更新
你可以配合JavaScript程序來完成緩存更新
CACHE:
這個是manifest文件的默認入口,在此入口之后羅列的文件 (或直接寫在CACHE MANIFEST后的文件)在它們下載到本地后會被緩存起來
NETWORK:
可選的,在此節后面所羅列的文件是需要訪問網絡的,即使用戶離線訪問了也會直接跳過緩存而訪問服務器
FALLBACK:
可選的,用來指定資源無法訪問時的回調頁面。每一行包括兩個URI,第一個是資源文件URI,第二個是回調頁面URI。
html5緩存的更新問題:
方法有三種:
1、用戶清除了離線存儲的數據,這個不一定就是清理瀏覽器歷史記錄就可以做到的,因為不同瀏覽器管理離線存儲的方式不同。比如Firefox的離線存儲數據要到“選項”=>“高級”=>“網絡”=>“脫機存儲”里才可以清除。
2、manifest文件被修改,上面說的,你修改了manifest文件里所羅列的文件也不會更新緩存,而是要替換manifest文件//修改注釋更新# wanz app v1
3、使用JavaScript api編寫更新程序
方法12為自動更新,方法3為手動更新
1 var appCache = window.applicationCache; 2 appCache.update(); // 開始更新 3 if (appCache.status == window.applicationCache.UPDATEREADY) {
appCache.swapCache(); // 得到最新版本緩存列表,並且成功下載資源,更新緩存到最新
}
