為啥要緩存:
1. 緩存的優點:
1)加快瀏覽器加載網頁的速度,優化用戶體驗,讓用戶更快速的打開我們的網頁;
2)減少對服務器的訪問次數,減輕服務器的負擔;
3)節省帶寬(就是節省錢...,因為很多帶寬服務其實是按流量來計費的,同樣對用戶也可以省4G、5G流量...也省錢了)
2.有啥缺點:
如果資源一直被緩存了,那當資源發生更改時,用戶就無法獲取最新的信息了! 所以緩存雖好,可不能亂用。
強緩存:
什么是強緩存?強制?沒錯,就是強制把資源緩存起來? 那不就是會有上面說的缺點了嗎?
是的,那為啥還要用強緩存呢?什么情況下要用強緩存呢?又到底怎么用呢?
強緩存是利用http頭中的Expires 和 Cache-Control兩個字段來控制的:
Expires

從圖中可以看到,它的值是一個絕對的時間,這個時間代表資源的失效時間,就是說在這個時間之前緩存始終有效,始終會讀取緩存中的數據。但是,這里會有一個明顯的缺點:因為它是一個絕對時間,當服務器時間與客戶端時間有偏差時,就可能會導致緩存失效,比如用戶隨意修改了本地時間...
Cacha-Control

http1.1加入了Cache-Control ,上圖中可以看到它的值:max-age=2592001,表示資源的最大有效時間的“秒數”,是一個相對值,不會因為用戶修改本地時間而導致失效。除了mas-age之外還有其他一些值:
1)public/private: public表示客戶端和代理服務器(如CDN)都可以緩存,private(默認值)表示只有客戶端可以緩存;
2)no-cache/no-store: no-cache客戶端緩存內容,但是是否使用緩存需要經過協商緩存來驗證決定;no-store 所有內容都不會被緩存,即不使用強緩存,也不使用協商緩存;
PS: Expires和Cache-Control可以在服務端配置為同時啟用,同時啟用的時候Cache-Control優先級更高
協商緩存:
協商緩存就是強制緩存失效后,瀏覽器攜帶緩存標識向服務器發起請求,由服務器根據緩存標識決定是否使用緩存的過程:
協商緩存是通過兩對值來設置的: Last-Modified/If-Modified-Since 和 ETag/If-None-Match

Last-Modified/If-Modified-Since:
1) 瀏覽器第一次發送請求,讓服務端在response header中返回請求的資源上次更新時間(Last-Modified的值),瀏覽器會存下這個時間;
2)當瀏覽器下次請求時,request header中帶上If-Modified-Since(即保存的Last-Modified的值)。根據瀏覽器發送的修改時間和服務端的wh修改時間進行比對,一致的話代碼資源沒有改變,服務端返回正文為空的響應,讓瀏覽器在緩存中讀取資源,從而減少請求消耗。
缺點:
1、從上圖可以看到Last-Modified保存的是絕對時間,並且是精確到秒,所以如果資源在1秒內修改了多次的話,那就無法識別;
2、對於文件只改變了修改時間,內容不變,這時候也會使緩存失效,其實這個時候我們是不希望客戶端重新請求的;
3、某些服務器不能精確的得到文件的最后修改時間;
ETag/If-None-Match:
1) 瀏覽器第一次發送一個請求得到ETag的值,然后在下一次請求request header中帶上If-none-match(即保存的ETag的值);
2)通過發送的ETag的值和服務器重新生成的ETag的值進行比對,如果一致代表資源沒有改變,服務器返回的正文為空的響應,讓瀏覽器從緩存中讀取資源,從而減少請求消耗。
ETag的工作機制跟Last-Modified基本一樣。但是,ETag是對資源內容使用抗碰撞散列函數(我也不知道是啥),使用最近修改的時間戳的哈希值。ETag解決了Last-Modified上述問題。
缺點:ETag雖然能解決問題,但也並非完美,ETag每次服務端生成都需要進行讀寫操作(因為要生成hash),而Last-Modified只需要讀取操作,ETag消耗更大一些。
Last-Modified 和 ETag同樣可以同時配置,服務器會優先驗證ETag,一致的情況下,才會繼續比對Last-Modified,最后才決定是否返回304。
精確度上,ETag更高,性能上Etag稍微低一點(因為要生成hash)
由此可見,協商緩存其實受強緩存的影響,強緩存過期了且Cache-Control不為no-store時是否緩存才由協商緩存決定。
