瀏覽器快取詳解

雲水搖啊搖發表於2017-06-15

第一次請求了 100 個檔案, 再次訪問的時候,如果全部重新請求, 非常浪費時間, 也很笨拙.

分析:

 因為有些檔案, 在使用者的多次請求中, 都是相同的, 如果多次請求都重複請求這個檔案, 無疑是一種浪費.

那麼就想到了快取: 把資源快取到本地, 再次請求的時候直接使用本地的快取檔案.

走極端:

 把所有的檔案都快取起來.

分析:

 這樣也不行, 因為在請求過來的 100 個檔案中, 可能有一部分是長久不變的, 有一部分是隔一段時間就變的,
 還有的檔案是每次都不一樣的.

那麼怎麼辦?

 要區分這些檔案, 快取的主動方(瀏覽器) 說: 我要知道我要不要快取一個檔案, 我要知道下次請求的時候對於
 某個檔案我到底能不能直接用快取, 還是需要重新請求.

OK.

伺服器說: 那我跟你說每個檔案的你要不要快取, 什麼時候不能用快取.
然後伺服器就在響應的時候, 新增一個響應頭 Expires

 類似這樣:Expires: Thu, 01 Dec 1994 16:00:00 GMT (必須是GMT格式)

瀏覽器得到這個檔案之後, 先使用這個檔案.
過了一會使用者重新請求了

 瀏覽器把 Expires 標記的時間 a, 和當前請求的時間 b 做個對比, 如果是這樣
      a....b  // 說明過期了, 那麼就重新請求
      b....a  // 咦還沒過期, 還能吃

與 Expires 有同樣功能的還有 Cache-Control, Parama 等響應頭
Cache-Control 是 HTTP 1.1 提出的, Expires 是 HTTP 1.0 提出的, 前者比後者優先順序高–在同時使用的時候.

然後, 瀏覽器發現不對, 這個檔案過期了, 我重新拿過來的怎麼還是和過期的一樣, 你丫騙我.
伺服器說: 那我能怎麼辦, 你又要過期時間, 還不能不給, 那哪能每個檔案的過期時間我都能精確算出來, 那個檔案明明我覺得
它經常變, 誰知道它一直都不變.

OK.

伺服器給出了個解決方案:

 你看這樣, 我呢, 把每個檔案算出來一個值, 只要檔案變化了, 這個值就會改變. 然後把這個值扔給你。
 你如果發現快取過期了, 請求的時候把這個值也給我.
 我來看看這個值和我這邊的值是不是一樣的
 如果是一樣的, 那麼說明這個檔案沒有變對不對, 那我就不給你檔案了,給你一個 304 你再繼續使用快取檔案

這個值使用 Etag 來標記,
客戶端在快取過期重新請求的時候, 加上一個頭 If-None-Match:(Etag的值)
OK.

伺服器又說了, 哎這樣的話我還想到另外一種方案

 我給你檔案的時候標記一下這個檔案最後修改的時間, 你要是發現快取過期了, 重新請求的時候把這個時間給我
 我比較一下我這邊記錄的最新的檔案更改時間, 如果兩個相同不就說明檔案沒改, 對不對.

伺服器給客戶端的時間叫: Last-Modified
客戶端返回過來的是: If-Modified-Since(Last-Modified 的值)

相關文章