http緩存指的是: 當客戶端向服務器請求資源時,會先抵達瀏覽器緩存,若是瀏覽器有「要請求資源」的副本,就能夠直接從瀏覽器緩存中提取而不是從原始服務器中提取這個資源。node
常見的http緩存只能緩存get請求響應的資源,對於其餘類型的響應則無能爲力,因此後續說的請求緩存都是指GET請求。nginx
http緩存都是從第二次請求開始的。第一次請求資源時,服務器返回資源,並在respone header頭中回傳資源的緩存參數;第二次請求時,瀏覽器判斷這些請求參數,命中強緩存就直接200,不然就把請求參數加到request header頭中傳給服務器,看是否命中協商緩存,命中則返回304,不然服務器會返回新的資源。segmentfault
瀏覽器在請求某一資源時,會先獲取該資源緩存的header信息,判斷是否命中強緩存(cache-control和expires信息),若命中直接從緩存中獲取資源信息,包括緩存header信息;本次請求根本就不會與服務器進行通訊。
狀態碼爲200
瀏覽器
Expires是http1.0的規範,它的值是一個絕對時間的GMT格式的時間字符串,這個時間表明這這個資源的失效時間,只要發送請求時間是在Expires以前,那麼本地緩存始終有效,則在緩存中讀取數據。失效的時間是一個絕對時間,當服務器與客戶端時間誤差較大時,會致使緩存混亂。若是同時出現Cache-Control:max-age和Expires,那麼max-age優先級更高。緩存
Cache-Control是在http1.1中出現的,主要是利用該字段的max-age值來進行判斷,它是一個相對時間,例如Cache-Control:max-age=3600,表明着資源的有效期是3600秒。cache-control除了該字段外,還有下面幾個比較經常使用的設置值:服務器
類型 | 描述 |
---|---|
public | 客戶端和代理服務器均可以緩存該資源;客戶端在xxx秒的有效期內,若是有請求該資源的需求的話就直接讀取緩存,status code:200 ,若是用戶作了刷新操做,就向服務器發起http請求 |
private | 只讓客戶端能夠緩存該資源,代理服務器不緩存;客戶端在xxx秒內直接讀取緩存,status code:200 |
immutable | 客戶端在xxx秒的有效期內,若是有請求該資源的需求的話就直接讀取緩存,status code:200 ,即便用戶作了刷新操做,也不向服務器發起http請求 |
no-cache | 跳過設置強緩存,可是不妨礙設置協商緩存;通常若是你作了強緩存,只有在強緩存失效了才走協商緩存的,設置了no-cache就不會走強緩存了,每次請求都回詢問服務端 |
no-store | 不緩存,這個會讓客戶端、服務器都不緩存,也就沒有所謂的強緩存、協商緩存了 |
若是沒有命中強緩存,瀏覽器會發送請求到服務器,請求會攜帶第一次請求返回的有關緩存的header字段信息(Last-Modified/If-Modified-Since和Etag/If-None-Match),由服務器根據請求中的相關header信息來比對結果是否協商緩存命中;若命中,則服務器返回新的響應header信息更新緩存中的對應header信息,可是並不返回資源內容,它會告知瀏覽器能夠直接從緩存獲取;不然返回最新的資源內容。
狀態碼爲304
編碼
last-modified
記錄資源最後修改的時間。啓用強緩存後,請求資源以後的響應頭會增長一個last-modified
字段,當再次請求該資源時,請求頭中會帶有if-modified-since
字段,值是以前返回的last-modified
的值。服務端會對比該字段和資源的最後修改時間,若一致則證實沒有被修改,告知瀏覽器可直接使用緩存並返回 304;若不一致則直接返回修改後的資源,並修改last-modified
爲新的值。spa
但 last-modified
有如下兩個缺點:代理
爲了解決 last-modified
上述問題,有了 etag
。 etag
會基於資源的內容編碼生成一串惟一的標識字符串,只要內容不一樣,就會生成不一樣的 etag
。啓用 etag
以後,請求資源後的響應返回會增長一個 etag
字段,當再次請求該資源時,請求頭會帶有if-no-match
字段,值是以前返回的etag
值,服務端會根據該資源當前的內容生成對應的標識字符串和該字段進行對比,若一致則表明未改變可直接使用本地緩存並返回 304;若不一致則返回新的資源(狀態碼200)並修改返回的 etag
字段爲新的值。code
能夠看出 etag
比 last-modified
更加精準地感知了變化,因此 etag
優先級也更高。不過從上面也能夠看出 etag
存在的問題,就是每次生成標識字符串會增長服務器的開銷。因此要如何使用 last-modified
和 etag
還須要根據具體需求進行權衡。
一、用戶發起了一個http
請求後,瀏覽器顯示經過強緩存機制檢測瀏覽器中該資源是否有緩存,有則直接返回資源,狀態碼爲200,而且不會請求服務器。
二、假若強緩存失效後,瀏覽器會向服務器請求資源,服務器會根據瀏覽器帶過來的請求頭信息進行協商緩存的檢測,若協商緩存有效則直接返回資源,狀態碼爲304.
三、當協商緩存也失效後,服務器從新獲取資源返回給瀏覽器,狀態碼爲200。
res.setHeader('max-age': '3600 public') res.setHeader(etag: '5c20abbd-e2e8') res.setHeader('last-modified': Mon, 24 Dec 2018 09:49:49 GMT)
本文參考:
http://www.javashuo.com/article/p-axzbmxqe-w.html
https://www.jianshu.com/p/9c95db596df5