HTTP緩存

一、強緩存

不向服務器發送請求,直接從緩存中讀取資源。
有兩種方式:Expires和Cache-Control(若響應兩者都有,則Cache-Control優於Expires)
在這裏插入圖片描述

no-cache:(Cache but revalidate)
A cache will send the request to the origin server for validation before releasing a cached copy.
每次有請求發出時,緩存會將此請求發到服務器(該請求與本地緩存有關,服務器校驗請求中所描述的緩存是否過期,若未過期(返回緩存304),則緩存才使用本地緩存)

no-store:(No caching)
The cache should not store anything about the client request or server response. A request is sent to the server and a full response is downloaded each and every time.
緩存不得存儲任何關於客戶端請求和服務器響應的內容。每次由客戶端發起的請求都會走完成的響應內容。

max-age:資源被緩存(保持新鮮)的最大時間
在這裏插入圖片描述

對於強緩存,chrome瀏覽器的狀態碼:
200 OK(from disk cache)或是200 OK (from memory cache)
例如:請求某個圖片後,當瀏覽器再次訪問這個圖片時,發現有這個圖片的緩存,且緩存沒過期,所以就使用緩存。

當瀏覽器發現緩存過期後,緩存並不一定不能使用了比如文件雖然過了有效期,但內容並沒有發生改變,還是可以用緩存數據。所以,這個時候需要與服務器協商,讓服務器判斷本地緩存是否還能使用。那麼又怎麼判斷服務端文件有沒有更新呢?主要有兩種方式:
Last-Modified,If-Modified-since。

二、協商緩存

Once a resource is stored in a cache, it could theoretically be served by the cache forever. Caches have finite storage so items are periodically removed from storage. This process is called cache eviction. On the other side, some resources may change on the server so the cache should be updated. As HTTP is a client-server protocol, servers can’t contact caches and clients when a resource changes; they have to communicate an expiration time for the resource. Before this expiration time, the resource is fresh; after the expiration time, the resource is stale. Eviction algorithms often privilege fresh resources over stale resources. Note that a stale resource is not evicted or ignored; when the cache receives a request for a stale resource, it forwards this request with a If-None-Match to check if it is in fact still fresh. If so, the server returns a 304 (Not Modified) header without sending the body of the requested resource, saving some bandwidth.
  理論上來講,當一個資源被緩存存儲後,該資源應該可以被永久存儲在緩存中。由於緩存只有有限的空間用於存儲資源副本,所以緩存會定期地將一些副本刪除,這個過程叫做緩存驅逐。另一方面,當服務器上面的資源進行了更新,那麼緩存中的對應資源也應該被更新,由於HTTP是C/S模式的協議,服務器更新一個資源時,不可能直接通知客戶端更新緩存,所以雙方必須爲該資源約定一個過期時間,在該過期時間之前,該資源(緩存副本)就是新鮮的,當過了過期時間後,該資源(緩存副本)則變爲陳舊的。驅逐算法用於將陳舊的資源(緩存副本)替換爲新鮮的,注意,一個陳舊的資源(緩存副本)是不會直接被清除或忽略的,當客戶端發起一個請求時,緩存檢索到已有一個對應的陳舊資源(緩存副本),則緩存會先將此請求附加一個If-None-Match頭,然後發給目標服務器,以此來檢查該資源副本是否是依然還是算新鮮的,若服務器返回了 304 (Not Modified)(該響應不會有帶有實體信息),則表示此資源副本是新鮮的,這樣一來,可以節省一些帶寬。若服務器通過 If-None-Match 判斷後發現已過期,那麼會帶有該資源的實體內容返回
在這裏插入圖片描述
在這裏插入圖片描述
Etag、If-None-Match

  • 瀏覽器第一次向服務器請求一個資源,服務器在返回這個資源的同時,在respone的header加上ETag字段;
  • 瀏覽器再次跟服務器請求這個資源時,在request的header上加上If-None-Match,這個值就是上一次請求時返回的ETag的值;
  • 服務器再次收到資源請求時,再根據資源生成一個新的ETag,與瀏覽器傳過來If-None-Match比較,如果這兩個值相同,則說明資源沒有變化,返回304 Not Modified, 瀏覽器從緩存中加載資源,否則返回200 資源內容。與Last-Modified不一樣的是,當服務器返回304 Not Modified的響應時,由於ETag重新生成過,response header中還會把這個ETag返回,即使這個ETag跟之前的沒有變化

Last-Modified、If-Modified-Since

  • 瀏覽器第一次向服務器請求一個資源,服務器在返回這個資源的同時,在respone的header加上Last-Modified字段,表示該資源在服務器上的最後修改時間;

  • 瀏覽器再次向服務器請求這個資源時,在request的header上加上If-Modified-Since字段,這個值就是上一次請求時返回的Last-Modified的值;

  • 服務器收到資源請求時,比較If-Modified-Since字段值和被請求資源的最後修改時間,若資源最後修改時間較舊,則說明文件沒有修改,返回304 Not Modified, 瀏覽器從緩存中加載資源;若不相同,說明文件被更新,瀏覽器直接從服務器加載資源, 返回200;

  • 重新加載資源時更新Last-Modified Header

爲什麼有了Last-Modified,還要用Etag呢?

  • 一些文件也許會週期性的更改,但是他的內容並不改變(僅僅改變的修改時間),這個時候我們並不希望客戶端認爲這個文件被修改了,而重新GET;

  • 某些文件修改非常頻繁,比如在秒以下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改無法判斷(或者說UNIX記錄MTIME只能精確到秒);

  • 某些服務器不能精確的得到文件的最後修改時間。

對於上述情景,利用ETag能夠更加準確的控制緩存,因爲ETag是服務器自動生成的資源在服務器端的唯一標識符,資源每次變動,都會生成新的ETag值。Last-Modified與ETag是可以一起使用的,但服務器會優先驗證ETag。

響應中Age與Date

  • Date:原服務器第一次響應的時間
  • Age:HTTP/1.1 uses the Age response-header to convey the estimated age of the response message when obtained from a cache. The Age field value is the cache’s estimate of the amount of time since the response was generated or revalidated by the origin server.

That means the presence of the header field Age: 0 means that the received response was sent by an intermediate cache and is only zero seconds old. So it was probably just fetched from the origin server before sending it to the client.
從上面可以看出,Age表示中間環節(CDN或緩存服務器)從服務器拿到數據之後的時間。如果是客戶端看到是0秒,代表是從服務器拿到的最新的數據。

三、將強緩存和協商緩存放在一張圖中

在這裏插入圖片描述

參考:https://segmentfault.com/a/1190000016872406
https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章