前言
之前看完了李智慧老師著的《大型網站技術架構-核心原理與案例分析》這本書,書中多次提起瀏覽器快取的話題,恰是這幾天生產又遇到了一個與快取的問題,發現自己書是沒少看,正經走心的內容卻不多,這次就藉著工作中遇到的問題,一併把與網頁快取相關的HTTP頭部資訊總結一番,一來總結給自己看,以便後期查閱;二來把自己的想法和園中朋友分享,互相指點,如此,豈不妙哉!!!
簡單的總結來說,在HTTP中與網頁快取相關的HTTP頭部資訊分為以下三組:
Last-Modified
和If-Modified-Since
ETags
和If-None-Match
Expires
和Cache-Control
下面就分別對這三組HTTP頭進行詳細的說明和總結!
Last-Modified和If-Modified-Since
在HTTP中Last-Modified
與If-Modified-Since
都是用於記錄頁面最後修改時間的HTTP頭資訊,二者的區別如下:
Last-Modified
是由伺服器往客戶端傳送的HTTP
頭;If-Modified-Since
是由客戶端往伺服器傳送的頭。
所以,請牢牢記住上述基本知識點,這樣才能工作中分析請求包時不會暈頭轉向。
如上圖所示,使用者通過瀏覽器第一次請求相關網頁時,伺服器會返回一個Last-Modified:Mon, 26 Apr 2019 13:22:17 GMT
這樣的請求頭;當使用者再次訪問對應的網頁時,瀏覽器會將伺服器響應的Last-Modified
值賦給If-Modified-Since
,接下來,瀏覽器會帶著If-Modified-Since:Mon, 26 Apr 2019 13:22:17 GMT
這樣的請求頭去訪問伺服器應用。伺服器收到請求後,會將這個對應網頁的更新時間與If-Modified-Since
進行比對以決定是返回304重定向碼還是200成功碼。
ETags和If-None-Match
通過上面的總結,我們知道Last-Modified
和If-Modified-Since
只能判斷資源的最後修改時間,以此來決定是否使用快取。而ETags
和If-None-Match
則比較更高階一點。通過ETags
和If-None-Match
,我們可以對資源的任何屬性進行判斷,以此判斷是否使用快取。同樣的,我們也需要記住ETags
和If-None-Match
的兩個知識點:
ETags
是由伺服器往客戶端傳送的HTTP
頭;If-None-Match
是由客戶端往伺服器傳送的頭。
請求邏輯與Last-Modified
和If-Modified-Since
大致一樣,不同之處就是在伺服器端的判斷。比如有些特定的場合下,一些靜態的檔案,可能會被頻繁的更新,但是檔案內容沒有變化,這時候如果使用Last-modified
,伺服器端始終返回最新的內容給瀏覽器,而Etag
是根據檔案內容來的,如果內容沒有變化的話,始終會讓瀏覽器使用本地快取的檔案。所以,使使用ETag
可以更好的避免一些不必要的伺服器相應。
Expires和Cache-Control
新增Expires
頭能有效的利用瀏覽器的快取能力來改善頁面的效能,能在後續的頁面中有效避免很多不必要的HTTP請求,WEB伺服器使用Expires
頭來告訴Web客戶端它可以使用一個元件的當前副本,直到指定的時間為止。例如:Expires:Thu,15 Apr 2019 20:00:00 GMT;
這個告訴瀏覽器快取有效性持續到2019年4月15日為止,在這個時間之內相同的請求使用快取,這個時間之外使用HTTP請求。與上面說到的Last-Modified
和If-Modified-Since
和ETags
和If-None-Match
相比,是能夠節省一點頻寬的,因為可能會少發一次HTTP請求。
但是Expires
有一個明顯的缺點;由於返回的到期時間是伺服器端的時間,這樣存在一個問題,如果客戶端的時間與伺服器的時間相差很大,那麼誤差就很大,所以在HTTP 1.1版開始,使用Cache-Control:max-age=秒替代
。如果Cache-Control
與Expires
同時存在,Cache-Control
生效。
由於現在基本上都在使用Cache-Control
,所以有必要對Cache-Control
進行詳細的總結一下。
Cache-Control
的可快取性:取值 說明 public HTTP返回的時候在Heaher中設定 Cache-Control
的值為public
。它代表,這個HTTP請求它返回的內容所經過的任何路徑中,包括中間的一些HTTP代理伺服器以及發出請求的客戶端瀏覽器,都可以進行對返回內容的快取操作private 發起請求的瀏覽器才能使用返回資料的快取 no-cache 可以在本地或者proxy伺服器進行快取,每次發起請求都要去伺服器驗證,伺服器返回可以使用快取,才可以真正使用本地快取,任何節點都不能直接使用快取 Cache-Control
的有效期取值 說明 max-age=seconds 最常用模式,表示過期的秒數 s-maxage=seconds 只有在代理伺服器才會生效,且代理伺服器會優先使用s-maxage max-stale=seconds 它是發起請求方,主動去帶著的header;在max-age過期後,但還在max-stale的有效期內,還可以使用過期的快取,不需要去原伺服器請求新的內容 Cache-Control
的其它取值取值 說明 no-store 瀏覽器或者proxy伺服器都不能存返回資料的快取,永遠都需要去伺服器請求新的資料 no-transform 主要用在proxy伺服器,表示不要去隨意改動返回的內容,比如壓縮什麼的
總結
這些細小的知識點,平時很少主動去關注,但是真正到分析問題的時候,很多時候卻是卡在這些細小的知識點上。還是那句話,細節決定成敗!大的知識點,大的流程,大家都可以說出一二,但是一旦細化了,才知道自己有好多的不懂,有好多的說不清楚。只有退潮了,才知道誰在裸泳!!!
2019年7月21日 於內蒙古呼和浩特。