【前端 · 面試 】HTTP 總結(九)—— HTTP 協商緩存

這是我參與8月更文挑戰的第9天,活動詳情查看:8月更文挑戰前端

最近我在作前端面試題總結系列,感興趣的朋友能夠添加關注,歡迎指正、交流。git

爭取每一個知識點可以多總結一些,至少要作到在面試時,針對每一個知識點均可以侃起來,不至於啞火。面試

前言

經過前面的介紹,咱們知道 HTTP 緩存分爲兩種:算法

  • 強緩存
  • 協商緩存

HTTP 緩存分類

在上一篇文章中,咱們瞭解了 HTTP 強緩存,今天咱們來了解一下協商緩存相關的內容。編程

協商緩存

特色

協商緩存,也稱爲對比緩存,從名稱能夠看出,它沒有強制緩存那麼霸道,能夠有商有量的來肯定是否使用緩存資源。瀏覽器

協商緩存機制下,瀏覽器須要發送緩存標識,去向服務器驗證緩存標識是否有效,進而判斷是從新發起請求、下載完整的響應,仍是從本地獲取緩存的資源。緩存

若是服務端提示緩存資源未改動(Not Modified),資源會被重定向到瀏覽器緩存,這種狀況下網絡請求對應的狀態碼是 304,好比:服務器

image-20210809205941306

規則

協商緩存的總體規則以下所示:markdown

image-20210809211515291

從上圖能夠看出,雖然客戶端仍然發起了 HTTP 請求服務器,可是服務器只作了標誌對比來確認是否使用緩存,若是確認使用緩存,就不會再返回具體的資源了。這樣作雖然沒有減小請求數量,可是極大減少了請求負荷,能夠明顯提高請求速度和減少網絡帶寬。網絡

上圖是緩存標識正常有效的時序圖,但其實協商緩存的驗證結果也存在兩種狀況:

  • 標識有效
  • 標識過時

協商緩存須要配合強緩存使用,使用協商緩存須要先設置 Cache-Control:no-cache 或者 pragma:no-cache 來告訴瀏覽器不走強緩存。

標識過時

image-20210809211805478

屬性

對於協商緩存來講,緩存標識的傳遞是咱們着重須要理解的,它在 Response Header 和 Request Header 之間進行傳遞。

緩存標識能夠分爲兩類:

  • Last-Modified 和 If-Modified-Since
  • Etag 和 If-None-Match

咱們通常會說,協商緩存的緩存標識是 Last-Modified(最後修改時間) 和 Etag(標籤或名稱),由於它們兩個都是由服務端肯定並返回的。

瀏覽器攜帶的是具備判斷意味的屬性 —— If-Modified-Since(從什麼時間以來是否改變) 和 If-None-Match(是否匹配不到)。

緩存標識的攜帶位置以下圖所示:

image-20210810115518959

在具體的網絡請求中,緩存標識以下圖所示:

image-20210810141436762

Last-Modified 和 If-Modified-Since

Last-Modified 和 If-Modified-Since 是 HTTP 1.0 引入的。

Last-Modified

當瀏覽器第一次訪問一個資源的時候,服務器會在 Response 、Header 中返回一個 Last-Modified,表明這個資源最後的修改時間。

If-Modified-Since

再次請求服務器時,請求頭會攜帶此字段,值爲上次請求時服務器返回的 Last-Modified 的值。

服務器收到請求後發現有頭 If-Modified-Since 則與被請求資源的最後修改時間進行比對:

  • 若資源的最後修改時間大於 If-Modified-Since,說明資源又被改動過,則響應整片資源內容,返回狀態碼 200 和最新的資源,響應頭中攜帶最新的緩存標識 Last-Modified。
  • 若資源的最後修改時間小於或等於 If-Modified-Since,說明資源無新修改,則響應 HTTP 304,告知瀏覽器繼續使用所保存的 cache。

缺陷

使用 Last-Modified 是有必定缺陷的:

  • 若是資源更新的速度是秒如下單位,那麼該緩存是不能被使用的,由於 If-Modified-Since 只能檢查到以秒爲最小計量單位的時間差。
  • 若是文件是經過服務器動態生成的,那麼該方法的更新時間永遠是生成的時間,儘管文件可能沒有變化,因此起不到緩存的做用。
  • 咱們編輯了文件,但文件的內容沒有改變。服務端並不清楚咱們是否真正改變了文件,它仍然經過最後編輯時間進行判斷。所以這個資源在再次被請求時,會被當作新資源,進而引起一次完整的響應——不應從新請求的時候,也會從新請求。

爲了解決上面服務器沒有正確感知文件變化的問題,Etag 做爲 Last-Modified 的補充出現了。

Etag 和 If-None-Match

Etag 和 If-None-Match 是一對報文頭,屬於HTTP 1.1。

ETag 和 If-None-Match 的值是一串 hash 碼,表明的是一個資源的標識符,當服務端的文件變化的時候,它的 hash 碼會隨之改變。

Etag

服務器響應請求時,告訴瀏覽器當前資源在服務器的惟一標識(生成規則由服務器決定)。

ETag 又有強弱校驗之分,若是 hash 碼是以 "W/" 開頭的一串字符串,說明此時協商緩存的校驗是弱校驗的,只有服務器上的文件差別(根據 ETag 計算方式來決定)達到可以觸發 hash 值後綴變化的時候,纔會真正地請求資源,不然返回 304 並加載瀏覽器緩存。

If-None-Match

再次請求服務器時,經過此字段通知服務器客戶段緩存數據的惟一標識。

服務器收到請求後發現有頭 If-None-Match 則與被請求資源的惟一標識進行比對:

  • 不一樣,說明資源又被改動過,則響應整片資源內容,返回狀態碼 200。
  • 相同,說明資源無新修改,則響應 HTTP 304,告知瀏覽器繼續使用所保存的 cache。

缺陷

Etag 的生成過程須要服務器額外付出開銷,會影響服務端的性能,這是它的弊端。

所以啓用 Etag 須要咱們審時度勢:

  • Etag 並不能替代 Last-Modified,它只能做爲 Last-Modified 的補充和強化存在。
  • Etag 在感知文件變化上比 Last-Modified 更加準確,優先級也更高。
  • 當 Etag 和 Last-Modified 同時存在時,以 Etag 爲準。

兩種屬性比較

  • 在精確度上,Etag 要優於 Last-Modified,Last-Modified 的時間單位是秒,若是某個文件在 1 秒內改變了屢次,那麼他們的 Last-Modified 其實並無體現出來修改,可是 Etag 每次都會改變確保了精度。
  • 在性能上,Etag 要遜於 Last-Modified,畢竟 Last-Modified 只須要記錄時間,而 Etag 須要服務器經過算法來計算出一個 hash 值。 在優先級上,服務器校驗優先考慮 Etag。

總結

總結一下上面的內容:

  • 協商緩存是依靠緩存標識來判斷資源是否有效。
  • 緩存標識包括 Last-Modified(If-Modified-Since)和 Etag(If-None-Match)。
  • 響應頭攜帶的是 Last-Modified 和 Etag。
  • 請求頭攜帶的是 If-Modified-Since 和 If-None-Match。
  • Etag 是 Last-Modified 的補充和完善,並不能徹底替代 Last-Modified。
  • Etag 的優先級高於 Last-Modified。
  • Last-Modified 的性能要高於 Etag,可是精確性卻遜色於 Etag。

以上就是 HTTP 協商緩存的相關內容。

~

~本文完,感謝閱讀!

~

學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!

你們好,我是〖編程三昧〗的做者 隱逸王,個人公衆號是『編程三昧』,歡迎關注,但願你們多多指教!

你來,懷揣指望,我有墨香相迎! 你歸,不管得失,惟以餘韻相贈!

知識與技能並重,內力和外功兼修,理論和實踐兩手都要抓、兩手都要硬!

相關文章
相關標籤/搜索