HTTP緩存是怎樣的一種存在
情景再現
在某次接口測試中,發現這樣一種情況:
產品功能需求是這樣的:點擊APP頁面上的某個按鈕,客戶端會向服務端發送一個URL請求。
然而Charles抓包發現,***次點擊該按鈕時可以正常發送請求,后來再多次點擊時就不發送該請求了。
What?。。。不科學呀!
原因排查
首先查看了相關代碼,的確是每次執行該點擊操作都會發送請求的,沒有任何問題。可是為什么后來不再發送請求了呢?
經過深入了解,原來是http緩存導致的。
下面跟著小編學習一下http緩存的相關知識,你就明白是怎么回事了~
知識科普
1. http緩存是怎樣的一種存在
1)什么是緩存
我們平時說的緩存,通常指的是Web緩存,它存在于服務器和客戶端之間,是一種保存資源副本并在下次請求時直接使用該副本的技術。當Web緩存發現請求的資源已經被存儲,它會攔截請求,返回該資源的拷貝,而不會去源服務器重新下載。
2)為什么要使用緩存技術
這是因為,通常情況下通過網絡獲取內容速度慢成本高,有些響應需要在客戶端和服務器之間進行多次往返通信,這就拖延了瀏覽器可以使用和處理內容的時間,同時也增加了訪問者的數據成本。通過緩存,使用資源副本,大大減少獲取資源時間,能夠減少網絡帶寬消耗、減少延遲與網絡阻塞,同時降低服務器壓力,提高服務器性能。
3)http緩存又是怎么回事呢
Web緩存從實現方式大致可以分以下幾種類型:
- 數據庫數據緩存;
- 服務器端緩存(包括代理服務器緩存和CDN緩存);
- 瀏覽器端緩存;
- Web應用層緩存。
http緩存就是Web緩存中的瀏覽器端緩存中的基于http協議實現的那一種,也是平時最常見的一種緩存。
2.http緩存是如何工作的
在這一小節我們先了解下http請求資源緩存的工作流程,然后對流程中細節進行解釋說明,你就會對http緩存的工作原理有更深入的認識。
1)http請求資源的工作流程
***次請求服務器資源時,沒有緩存文件,直接向服務器發送請求。流程如下:
***次請求流程圖
第二次及以后再請求服務器資源時,本地已有緩存,請求端會進行資源是否過期及更新等相關判斷,決定是否發送請求,或發送帶哪些條件式判斷字段的請求,服務端視判斷結果決定返回的響應狀態及是否返回資源。具體流程如下:
非***次請求流程圖
以上是http緩存請求資源的工作流程圖,http緩存是通過 HTTP 協議頭里的Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段來控制文件緩存的機制,下面對流程中的各個字段及過程進行詳細說明:
1)控制緩存的相關字段
- Pragma 設置頁面是否緩存,為Pragma則緩存,no-cache則不緩存。它http1.0遺留的字段,當它和cache-control同時存在的時候,會被cache-control覆蓋。
- Expires 定義緩存過期時間,這個時間相對服務器上的時間而言的,它也是http1.0遺留的字段。如Expires:Thu, 30 Aug 2018 08:14:36 GMT。
- Cache-Control 也是定義緩存過期時間,針對“Expires時間是相對服務器而言,無法保證和客戶端時間統一”的問題而在http1.1協議中新增的,若報文中同時出現了Expires 和Cache-Control,則以Cache-Control 為準。Cache-Control字段的指令說明如下:
- no-cache特別注意,這個不是不被緩存的意思!!是會被緩存的,只不過每次在向客戶端提供響應數據時,緩存都要向服務器評估緩存響應的有效性;
- no-store響應不被緩存;
- max-age設置緩存的存在時間,相對于發送請求的時間,單位為s。在緩存時間內,如果有請求這個資源,瀏覽器不會發出 http請求,而是直接使用本地緩存的文件。如Cache-Control: max-age=604800。
2)控制協商緩存的字段
- Last-Modified/If-Modified-Since
- Last-Modified 標示這個響應資源的***修改時間,如Last-Modified:Tue, 20 Dec 2016 05:01:10 GMT;
- If-Modified-Since 當帶著If-Modified-Since頭訪問服務器請求資源時,服務器會檢查Last-Modified,如果Last-Modified的時間早于或等于If-Modified-Since則會返回一個不帶主體的304響應,否則返回200并重新返回資源。
- ETag/If-None-Match
- ETag 是一個響應首部字段,它是根據實體內容生成的一段hash字符串,作為資源的唯一標識,由服務端產生,如:ETag:"0q9QPk4kQr2st/XMvRW8yqEt2iw=";
- If-None-Match 是一個條件式的請求首部。web服務器收到請求后發現有頭If-None-Match則與被請求資源的相應校驗串Etag進行比對,如果匹配服務器才會返回帶有所請求資源實體的200響應,否則服務器會返回不帶實體的304響應,流程見下圖。如:If-None-Match:"eOM1rC2lomM4oUbYNn0QD/Y4WLg="。
注:ETag優先級比Last-Modified高,同時存在時會以ETag為準。
協商緩存流程
學以致用
***,回到文章開頭的情景進行分析,根據下圖中請求的Response 頭部信息中Expires字段得知,http請求的資源有3個小時的緩存時間,而報文中同時也出現了Cache-Control: max-age=10800,也表示資源在本地緩存3個小時,此時無論二者時間是否一致,以Cache-Control為準。這也就解釋了后來(3個小時以內)再次點擊按鈕時不再發送請求的原因。
請求Response頭部