前言
最近一個好奇的測試同學問我,你們前端開發完成後,每次都讓我們清緩存或者Ctrl+f5強制重新整理,我能不能每次不用強制重新整理,就能看到你們更新的内容呢。我說是可以做到的,我來跟你講講浏覽器的緩存政策。我相信應該有不少的同學在工作中都會遇到這種情況,讓你的測試同學清緩存等。
緩存
浏覽器緩存是為了節約網絡的資源加速浏覽,浏覽器在使用者磁盤上對最近請求過的文檔進行存儲,當通路者再次請求這個頁面時,浏覽器就可以從本地磁盤或記憶體中顯示文檔,這樣就可以加速頁面的閱覽。
浏覽器緩存主要有兩類:強緩存:
cache-control
,
Expires
緩存協商:
Last-modified
Etag
。
所有的緩存政策都是通過http header裡設定的。
強緩存
當浏覽器去擷取資源的時候,不給伺服器發請求,直接從緩存中讀取。
Expires(過期時間)
Expires(緩存過期時間)是
http1.0
的産物,用來指定資源的到期時間,是服務端傳回的時間點。
從上面圖我們可以看出在
Expires: Thu, 20 Jan 2022 07:50:17 GMT
在這之後會過期,請求改資源不會從緩存中擷取。
缺點
: 時間的判斷是通過本地判讀的,如果本地時間調大了,緩存可能會失效。
Cache-Control
Cache-Control是
http1.1
控制緩存的重要字段,如果Cache-Control在,它的優先級會比Expires高。常用的值如下
名稱 | 描述 |
---|---|
public | 表示可以被用戶端和代理伺服器緩存 |
private | 表示隻可以被用戶端緩存 |
max-age=30 | 機關為秒(s), 表示30s之内,從緩存中擷取 |
s-maxage=30 | 根 一樣,表示隻在代理中生效 |
no-sotre | 不緩存任何響應 |
no-cache | 資源被緩存,但馬上失效,下次請求會通過 驗證資源是否過去 |
max-stale=30 | 在30s之内,緩存過期也從緩存中讀取 |
協商緩存
協商緩存就是強制緩存失效後,浏覽器攜帶緩存辨別向伺服器發起請求,由伺服器根據緩存辨別決定是否使用緩存的過程,主要有兩組配合使用:
-
和Last-Modified
If-Modified-Since
-
Etag
If-None-Match
Last-Modified和If-Modified-Since
浏覽器在第一次通路資源的時候,伺服器傳回資源的同僚,會在
Response header
中添加
Last-Modified
的key,表示該資源最後修改時間,浏覽器接收後緩存
檔案
header
,下次請求該資源,浏覽器會檢測到有
Last-Modified
這個請求頭,于是在請求中會添加
If-Modified-Since
這個請求頭,值就是之前
Last-Modified
中的值。伺服器收到請求後,會根據
If-Modified-Since
中的值去判斷資源是否更新。
如果值相等,就傳回
304
狀态碼和空的響應體,浏覽器收到後會通過緩存擷取。可以看下圖
如果不相等,就傳回内容和200的狀态碼。
Etag
If-None-Match
Etag
If-None-Match
Etag是伺服器響應請求時,傳回目前資源檔案的一個唯一辨別(由伺服器生成),隻要資源有變化,Etag就會重新生成。浏覽器在下一次加載資源向伺服器發送請求時,會将上一次傳回的Etag值放到
Request header
裡的
If-None-Match
,伺服器隻需要比較用戶端傳來的If-None-Match跟自己伺服器上該資源的ETag是否一緻,就能很好地判斷資源相對用戶端而言是否被修改過了。
304
注意
:
ETag和If-None-Match
優先級高于
Last-Modified和If-Modified-Since
,同時存在則隻有
ETag和If-None-Match
生效。
應用部署設定規則
我們知道了浏覽器的緩存之後,在常見的web開發中我們應該怎麼設定呢。
現在大多數的應用是通過webpack打包的,打包生成的資源名稱會帶上
hash
值。下面是打包後的檔案
我們可以遵循之下規則
-
入口檔案不加強制緩存,設定成協商緩存index.html
-
線上上環境可以設定成強緩存。js 資源
因為我們每次打包之後,入口檔案會有變化,是以協商緩存會失效,會重新從伺服器擷取新的資源。而對應的js資源有hash的變化,是以有變化,會從伺服器中擷取。
結束語
浏覽器的緩存政策,我們就說到這了,快來學習下,跟你的測試小夥伴說一說。
如果你覺得該文章不錯,不妨
1、點贊,讓更多的人也能看到這篇内容
2、關注我,讓我們成為長期關系
3、關注公衆号「前端有話說」,裡面已有多篇原創文章,和開發工具,歡迎各位的關注,第一時間閱讀我的文章