HTTP緩存
緩存控制(強制緩存)
- 浏覽器發送請求,向服務端請求資源
- 伺服器做出響應并傳回攜帶有效期的資源
- 浏覽器緩存資源用于重用
HTTP/1.1
定義的
Cache-Control
頭用來區分對緩存機制的支援情況,
Request Headers
和
Response Headers
都支援這個屬性,通過它提供的不同的值來定義緩存政策:
- Cache-Control: no-store
- 緩存中不得存儲任何關于用戶端請求和服務端響應的内容
- 每次由用戶端發起的請求都會下載下傳完整的響應内容
- 用于某些變化非常頻繁的資料,例如秒殺頁面,實時排行榜等
- Cache-Control: no-cache
- 允許緩存但需要重新驗證,每次使用之前需要去伺服器端驗證,請求中所描述的緩存是否過期,若未過期傳回
,使用本地緩存副本304 Not Modified
- 允許緩存但需要重新驗證,每次使用之前需要去伺服器端驗證,請求中所描述的緩存是否過期,若未過期傳回
- Cache-Control: private
- 隻允許用戶端(浏覽器)使用的私有緩存
- Cache-Control: public
- 允許伺服器(中間代理、CDN等等)及用戶端使用的的緩存
- Cache-Control: max-age=31536000
- 緩存的生存時間設定(從響應封包的建立時開始計算,包含了在鍊路傳輸過程中所有節點所停留的時間)
- Cache-Control: must-revalidate
- 如果緩存不過期就可以繼續使用,過期了還想用就必須去伺服器驗證
條件請求(協商緩存)
浏覽器用
Cache-Control
做緩存控制隻能是重新整理資料,不能很好地利用緩存資料,又因為緩存會失效,使用前還必須要去伺服器驗證是否是最新版
浏覽器可以用兩個連續的請求組成驗證動作:
- 先是一個 HEAD,擷取資源的修改時間等元資訊
- 然後與緩存資料比較,如果沒有改動就使用緩存,節省網絡流量
- 否則就再發一個 GET 請求,擷取最新的版本
但這樣的兩個請求網絡成本太高了,是以
HTTP
協定就定義了一系列
If
開頭的條件請求字段,由伺服器檢查驗證資源是否過期,把兩個請求才能完成的工作合并在一個請求裡做:
-
配合If-Modified-Since/If-Unmodified-Since
,Last-modified
-
配合If-Match/If-None-Match
ETag
-
字段值中既可以用If-Range
時間值用作驗證,也可以用Last-Modified
标記作為驗證,但不能将兩者同時使用ETag
需要第一次的響應封包預先提供
Last-modified
和
ETag
,然後第二次請求時就可以帶上緩存裡的原值,驗證資源是否是最新的,如果資源沒有變,伺服器就回應一個
304 Not Modified
,表示緩存依然有效,浏覽器就可以更新一下有效期繼續使用
- Last-modified
- 檔案的最後修改時間
- ETag
- 一個檔案在一秒内修改了多次,但因為修改時間是秒級,是以這一秒内的新版本無法區分
- 一個檔案定期更新,但有時會是同樣的内容,實際上沒有變化,用修改時間就會誤以為發生了變化,傳送給浏覽器就會浪費帶寬
- Entity Tag 資源唯一辨別,解決修改時間無法準确區分檔案變化的問題
ETag 還有強 弱之分:
- 強 ETag 要求資源在位元組級别必須完全相符
- 弱 ETag 在值前有個“W/”标記,隻要求資源在語義上沒有變化,但内部可能會有部分發生了改變(例如 HTML 裡的标簽順序調整,或者多了幾個空格)
Cookie
工作過程
使用者通過首次通過浏覽器向服務端發送請求,此時的身份是未知的,伺服器不能知道使用者是誰,是以會利用
Set-Cookie
字段,以
key=value
的格式随着
Response Headers
發送給浏覽器
浏覽器根據服務端發送來的
Set-Cookie
身份辨別内容,将
Cookie
儲存,再次發送請求時就會在
Request Headers
中攜帶此資訊
伺服器在某些場景下會設定多個,浏覽器發送時不需要設定多個,用
Set-Cookie
隔開就可以了
;
時效
- Expires
- 過期時間,使用絕對時間點,例如:
expires=Wed, 02 Dec 2020 03:07:26 GMT;
- 過期時間,使用絕對時間點,例如:
- Max-Age
- 用的是相對時間,機關是秒,浏覽器用收到封包的時間點再加上
,就可以得到失效的絕對時間Max-Age
- 用的是相對時間,機關是秒,浏覽器用收到封包的時間點再加上
和
Expires
可以同時出現,兩者的失效時間可以一緻,也可以不一緻,但浏覽器會優先采用
Max-Age
計算失效期
Max-Age
作用域
- Domain 所屬域名
- Path 所屬路徑
浏覽器發送時會提取
Cookie
中的
URI
和
host
進行對比,隻有滿足條件的情況下才會發送
path
安全性
- HttpOnly
- 浏覽器中的js引擎通過
讀取document.cookie
資料,可以利用Cookie
的方式進行攻擊,XSS 跨站腳本
會告知浏覽器隻能使用HttpOnly
協定傳輸HTTP
,浏覽器會禁用掉有關Cookie
操作的所有apiCookie
- 浏覽器中的js引擎通過
- SameSite
- 預防
XCRF 跨站請求僞造
-
:嚴格禁止SameSite=Strict
随跳轉連結進行跨站發送Cookie
-
:允許SameSite=Lax
等安全方法,禁止GET/HEAD
跨站發送POST
- 預防
- Secure
-
隻能用Cookie
協定加密傳輸,明文的HTTPS
協定禁止發送(HTTP
本身不是加密的,在浏覽器中以明文方式存儲)Cookie
-
浏覽器中Cookie的管理
