文章目錄
- 使用HTML Meta 標籤
- 使用緩衝有關的HTTP訊息前序
- Cache-Control與Expires
- Last-Modified/ETag與Cache-Control/Expires
- Last-Modified與ETag
- 使用者操作行為與緩衝
====索引=====
【Web緩衝機制概述】1 – Web緩衝的作用與類型
【Web緩衝機制概述】2 – Web瀏覽器的緩衝機制
【Web緩衝機制概述】3 – 如何構建可緩衝網站
【Web緩衝機制概述】4 – HTML5時代的Web緩衝機制
【Web緩衝機制概述】5 – Web App時代的緩衝機制新思路
============
Web緩衝的工作原理
所有的緩衝都是基於一套規則來協助他們決定什麼時候使用緩衝中的副本提供服務(假設有副本可用的情況下,未被銷毀回收或者未被刪除修改)。這些規則有的在協議中有定義(如HTTP協議1.0和1.1),有的則是由緩衝的管理員設定(如DBA、瀏覽器的使用者、Proxy 伺服器管理員或者應用開發人員)。
瀏覽器端的緩衝規則
對於瀏覽器端的緩衝來講,這些規則是在HTTP協議頭和HTML頁面的Meta標籤中定義的。他們分別從新鮮度和校正值兩個維度來規定瀏覽器是否可以直接使用緩衝中的副本,還是需要去原始伺服器擷取更新的版本。
新鮮度(到期機制):也就是快取複本有效期間。一個快取複本必須滿足以下條件,瀏覽器會認為它是有效,足夠新的:
- 含有完整的到期時間控制頭資訊(HTTP協議前序),並且仍在有效期間內;
- 瀏覽器已經使用過這個快取複本,並且在一個會話中已經檢查過新鮮度;
滿足以上兩個情況的一種,瀏覽器會直接從緩衝中擷取副本並渲染。
校正值(驗證機制):伺服器返回資源的時候有時在控制頭資訊帶上這個資源的實體標籤Etag(Entity Tag),它可以用來作為瀏覽器再次請求過程的校正標識。如過發現校正標識不匹配,說明資源已經被修改或到期,瀏覽器需求重新擷取資源內容。
瀏覽器緩衝的控制使用HTML Meta 標籤
Web開發人員可以在HTML頁面的<head>節點中加入<meta>標籤,代碼如下:
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
上述代碼的作用是告訴瀏覽器當前頁面不被緩衝,每次訪問都需要去伺服器拉取。使用上很簡單,但只有部分瀏覽器可以支援,而且所有緩衝Proxy 伺服器都不支援,因為代理不解析HTML內容本身。
可以通過這個頁面測試你的瀏覽器是否支援:Pragma No-Cache Test 。
使用緩衝有關的HTTP訊息前序
一個URI的完整HTTP協議互動過程是由HTTP請求和HTTP回應群組成的。有關HTTP詳細內容可參考《Hypertext Transfer Protocol — HTTP/1.1》、《HTTP協議詳解》等。
在HTTP請求和響應的訊息前序中,常見的與緩衝有關的訊息前序有:
Cache-Control與Expires
Cache-Control與Expires的作用一致,都是指明當前資源的有效期間,控制瀏覽器是否直接從瀏覽器緩衝取資料還是重新發請求到伺服器取資料。只不過Cache-Control的選擇更多,設定更細緻,如果同時設定的話,其優先順序高於Expires。
Last-Modified/ETag與Cache-Control/Expires
配置Last-Modified/ETag的情況下,瀏覽器再次訪問統一URI的資源,還是會發送請求到伺服器詢問檔案是否已經修改,如果沒有,伺服器會只發送一個304回給瀏覽器,告訴瀏覽器直接從自己本地的緩衝取資料;如果修改過那就整個資料重新發給瀏覽器;
Cache-Control/Expires則不同,如果檢測到本地的緩衝還是有效時間範圍內,瀏覽器直接使用本機複本,不會發送任何請求。兩者一起使用時,Cache-Control/Expires的優先順序要高於Last-Modified/ETag。即當本機複本根據Cache-Control/Expires發現還在有效期間內時,則不會再次發送請求去伺服器詢問修改時間(Last-Modified)或實體標識(Etag)了。
一般情況下,使用Cache-Control/Expires會配合Last-Modified/ETag一起使用,因為即使伺服器設定緩衝時間, 當使用者點擊[重新整理] 按鈕時,瀏覽器會忽略緩衝繼續向伺服器發送請求,這時Last-Modified/ETag將能夠很好利用304,從而減少響應開銷。
Last-Modified與ETag
你可能會覺得使用Last-Modified已經足以讓瀏覽器知道本地的快取複本是否足夠新,為什麼還需要Etag(實體標識)呢?HTTP1.1中Etag的出現主要是為瞭解決幾個Last-Modified比較難解決的問題:
- Last-Modified標註的最後修改只能精確到秒級,如果某些檔案在1秒鐘以內,被修改多次的話,它將不能準確標註檔案的新鮮度
- 如果某些檔案會被定期產生,當有時內容並沒有任何變化,但Last-Modified卻改變了,導致檔案沒法使用緩衝
- 有可能存在伺服器沒有準確擷取檔案修改時間,或者與Proxy 伺服器時間不一致等情形
Etag是伺服器自動產生或者由開發人員產生的對應資源在伺服器端的唯一識別碼,能夠更加準確的控制緩衝。Last-Modified與ETag是可以一起使用的,伺服器會優先驗證ETag,一致的情況下,才會繼續比對Last-Modified,最後才決定是否返回304。Etag的伺服器建置規則和強弱Etag的相關內容可以參考,《互動百科-Etag》和《HTTP Header definition》,這裡不再深入。
使用者操作行為與緩衝
使用者在使用瀏覽器的時候,會有各種操作,比如輸入地址後斷行符號,按F5重新整理等,這些行為會對緩衝有什麼影響呢?
通過上表我們可以看到,當使用者在按F5進行重新整理的時候,會忽略Expires/Cache-Control的設定,會再次發送請求去伺服器請求,而Last-Modified/Etag還是有效,伺服器會根據情況判斷返回304還是200;而當使用者使用Ctrl+F5進行強制重新整理的時候,只是所有的緩衝機制都將失效,重新從伺服器拉去資源。
相關有趣的分享:
《瀏覽器緩衝機制》:不同瀏覽器對使用者操作行為處理比較
《HTTP 304用戶端緩衝最佳化的神奇作用和用法》:強行在代碼層面比對檔案的Last-Modified時間,保證使用者使用Ctrl+F5進行重新整理的時候也能正常返回304
哪些請求不能被緩衝?
無法被瀏覽器緩衝的請求:
- HTTP資訊頭中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告訴瀏覽器不用緩衝的請求
- 需要根據Cookie,認證資訊等決定輸入內容的動態請求是不能被緩衝的
- 經過HTTPS安全加密的請求(有人也經過測試發現,ie其實在頭部加入Cache-Control:max-age資訊,firefox在頭部加入Cache-Control:Public之後,能夠對HTTPS的資源進行緩衝,參考《HTTPS的七個誤解》)
- POST請求無法被緩衝
- HTTP回應標頭中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的請求無法被緩衝