1. HTTP 緩存
DNS 緩存
假設訪問了百度,我們需要知道他的 ip 地址
首先瀏覽器會問windows
,如果不知道會問電信要,電信就會返回給瀏覽器,此時瀏覽器會緩存下來(一般是一天),然後在返回給瀏覽器,瀏覽器也會緩存下來(一般是幾分鐘)
HTTP 緩存
在響應頭中加入:
Cache-Control: public, max-age=3600, must-revalidate
Cache-Control
- public -- 公開內容,服務器和客戶端之間的所有代理都能對文件緩存,與之相反 private,只有客戶端能緩存
- max-age -- 緩存時間
- must-revalidate -- 必須重新校驗(這個校驗就叫做內容協商)
2. HTTP 內容協商
緩存過期以後還能重用嗎?
ETag
在響應頭中加入:
ETag: xxx // 比如文件的 MD5
當文件緩存失效的時候,客戶端就會發起請求,這次就不是普通請求了,而是協商請求,要帶上之前的 ETag
此時服務器會檢查文件是否有變化,如果沒有變化則返回 304 同時有一個空的響應,否則 200 和新文件的響應1
這樣瀏覽器就知道要刪除或者覆蓋之前的緩存(而不是延用之前的),什麼時候覆蓋,什麼時候刪除呢?如果響應頭裏還有 Cache-Control 那就是覆蓋,如果 Cache-Control=0 則是刪除
VS .
-----------------------------------------------------------------------------------
| | 緩存 (強緩存) | 內容緩存 (弱緩存) |
-----------------------------------------------------------------------------------
| HTTP/1.1 | Cache-Control: max-age=3600, ... | 請求頭: If-None-Match: ABC |
| HTTP/1.1 | ETag: ABC | 響應: 304 + 空 / 200 + 新內容 |
-----------------------------------------------------------------------------------
| HTTP/1.0 | Expire: 時間點A | 請求頭: If-Modified-Since: 時間點 B |
| HTTP/1.0 | Last-Modified: 時間點B | 響應: 304 + 空 / 200 + 新內容 |
3. 服務器禁用緩存
問:如果不加 Cache-Control,瀏覽器還會緩存嗎?
答:會
Get 請求一般會被緩存,例如 200,203(非權威信息),206(部分內容),300(多種選擇),301(永久重定向),400(已遷移)都會被瀏覽器緩存下來
就算我們不加 Cache-Control 也會被瀏覽器緩存下來,所以有些時候我們需要手動禁用緩存
Cache-Cintrol: max-age=0, must-revalidate
// 0 表示到達瀏覽器後就當場失效,
// must-revalidate 表示緩存失效以後可以用來協商
根據 MDN 說法,相當於如下寫法
Cache-Cintrol: no-cache
最爲嚴格的寫法,在加上如下:
Cache-Cintrol: no-store // 表示不允許協商
4. 瀏覽器禁用緩存
- 加上隨機數
- /xxxx?random=xxx
- 在請求頭中加入
- xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, max-age=0')
5. Pragma(過時)
是一個在 HTTP/1.0 中規定的通用首部,這個首部的效果依賴於不同的實現,所以在“請求-響應”鏈中可能會有不同的效果。它用來向後兼容只支持 HTTP/1.0 協議的緩存服務器,那時候 HTTP/1.1 協議中的 Cache-Control 還沒有出來。
由於 Pragma 在 HTTP 響應中的行爲沒有確切規範,所以不能可靠替代 HTTP/1.1 中通用首部 Cache-Control,儘管在請求中,假如 Cache-Control 不存在的話,它的行爲與 Cache-Control: no-cache 一致。建議只在需要兼容 HTTP/1.0 客戶端的場合下應用 Pragma 首部。
Pragma: no-cache