如今的Web應用愈來愈複雜,體驗愈來愈好。相應的,資源文件也愈來愈大,若是能讓客戶端在資源沒更新的狀況下,直接取用緩存的數據,那麼不只資源加載的更快,服務器壓力更小,也爲綠色地球作出了一份貢獻。程序員
程序員向來是追求最優,在設法緩存靜態資源之後,你們又找到了一些方法來緩存動態生成的內容。看來程序員們都是環境保護主義者(笑。緩存
從HTTP/1.0-HTTP/1.1,一共產生了3種控制緩存的方法:服務器
Cache-Control(響應頭,HTTP/1.1)代理
- Last-Modified(響應頭),If-Modified-Since(請求頭) - Etag(響應頭),If-None-Match(請求頭)
以上就是HTTP控制緩存的方法。code
除了這些,在第二個還有If-Unmodified-Since,第三個還有If-Match。但這兩個響應頭不是爲了控制緩存,而是爲了確認修改的資源的一致性。以後會介紹。資源
Expires: <http-date>
其中 <http-date> 的格式以下:io
Date: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT Example: Fri, 03 Nov 2017 03:22:39 GMT
當設置了Expires後,客戶端在此日期以前都不會去請求服務器,而是直接從緩存中取。
不過這樣也有一個問題:若是徹底不去請求服務器的話,在資源過時以前若是資源有更新,客戶端仍是使用着以前的資源。因此就產生了下面更加高級的緩存控制方法(第3、第四項方法)。ast
不過還有一個方法能解決這個問題:將資源的Expires設置爲一個足夠長的時間,而資源名爲資源的Hash值,這樣資源更新了之後,也使用的是不一樣的名稱。那麼就不存在上面的問題了。date
Expires只能設置具體的日期,這樣的話,若是客戶端與服務器的時間不一致,會致使緩存時間不正確,還有可能直接致使緩存失效。語法
HTTP/1.1的Cache-Control配合If-Modified-Since或If-None-Match則完美的解決了這個問題。
Cache-Control比較經常使用的指令以下:
可緩存性
過時控制
再驗證
其餘
上面列表中向服務器確認緩存是否有效的技術手段就是下文介紹的 Last-Modified/If-Modified-Since
和 ETag/If-None-Match
。
Last-Modified: <http-date>
Last-Modified頭是服務器告訴客戶端此資源的最後修改時間,客戶端則會將資源和這個時間都儲存起來。以後,根據Cache-Control的指令,若是須要同服務器確認資源的有效性的時候則會將這個時間放在If-Modified-Since頭中,供服務器進行比較,是返回304仍是200。
If-Modified-Since頭只會在GET和HEAD請求被附加進請求頭。
If-Unmodified-Since: <http-date>
通常來講在PUT, POST等方法使用,表示該次請求更新的資源的日期爲<http-date>,若是服務器檢測到現存資源的日期不爲<http-date>(即已經被其餘的方式更新了),則會失敗並返回412。
ETag: W/"<etag_value>" ETag: "<etag_value>"
If-None-Match: "<etag_value>"[, "<etag_value>"...] If-None-Match: W/"<weak_etag_value>"[, "<weak_etag_value>"]
若是將上面的 Last-Modified / If-Modified-Since
應用在動態的數據上的話,基本上沒有可行性。那麼就有了此方式的緩存。
在第一次請求的時候,服務器會附帶ETag頭。ETag的值是根據響應的內容來進行生成的,通常來講是內容(+其餘一些標識的)哈希值。以後,根據Cache-Control的指令,若是須要同服務器確認資源的有效性的時候則會將這個etag_value放在If-None-Match頭中,供服務器進行比較,是返回304仍是200。
在ETag的值前若是有W/
則表示這是一個弱Etag。弱ETag相等意味着這兩個內容語義上是相等的,強ETag相等則表示內容每個字節都相等。
舉個弱ETag的例子:返回的數據中帶有log信息,而兩次返回的數據是相同的,log不一樣。
還有一種語法:
If-None-Match: *
,基本上用在PUT, POST等上,用於上傳。表示要求上傳的文件在服務器上不存在。
If-Match: "<etag_value>"[, "<etag_value>"...] If-Match: W/"<weak_etag_value>"[, "<weak_etag_value>"]
對於GET, HEAD等請求,若是資源的ETag匹配上If-Match的值,則返回資源,不然返回412。
對於PUT, POST等請求,若是現有資源的Etag匹配上If-Match的值,那麼進行寫操做,不然失敗返回412。
----- 記得點贊 -----