前端缓存之HTTP缓存(二)
1.1 什么是HTTP緩存?
HTTP緩存:當客戶端向服務端請求資源時,會先去到瀏覽器緩存,如果瀏覽器緩存有需要請求資源的副本,就可以直接從瀏覽器緩存中提取,而不會去到服務器。
常見的http緩存都只能緩存get方式請求響應的資源,不能處理其他類型的響應。
HTTP緩存都是從第二次請求開始的,當第一次請求資源時,服務器會返回資源,并在請求頭中傳回資源的緩存參數;第二次請求時,瀏覽器會對這些參數進行判斷,命中強緩存的就返回200,不命中會把請求參數加到請求頭中傳給服務器,判斷是否命中協商緩存,命中協商緩存返回304(簡單點來說就是服務端已經執行了GET,但文件未發生變化),否則服務器會返回新的資源。
而HTTP緩存分為強緩存和協商緩存。強緩存如果生效,不需要再和服務器發生交互,而協商緩存不管是否生效,都需要與服務端發生交互。
1.1.1 強緩存
強緩存在緩存數據未失效的情況下(即Cache-Control的max-age沒有過期或者Expires的緩存時間沒有過期),那么就會直接使用瀏覽器的緩存數據,不會再向服務器發送任何請求。強制緩存生效時,http狀態碼為200。這個方式頁面加載的速度很快,性能好,但是在這期間,如果服務端的資源修改了,頁面上是無法獲取的,因為它不會再向服務器發送請求了。就好比如我們在實際開發中,修改了某個頁面的樣式,在頁面上刷新但修改的內容沒有生效,因為使用的是強緩存,這時候就需要Ctrl+F5。
header屬性:
-
Pragma(HTTP/1.0)
-
no-cache:不直接使用緩存,根據新鮮度來使用緩存,
響應頭不支持這個屬性,優先級最高,但在HTTP/1.1廢棄了
-
-
Cache-Control(HTTP/1.1)
-
no-cache:不直接使用緩存,根據新鮮度來使用緩存
-
no-store:不使用緩存,每次都是請求下載新資源
-
max-age:緩存時長
-
public/private:是否只能被單個用戶使用,默認為private
-
must-revalidate:每次訪問需要緩存校驗
請求頭和響應頭都支持這個屬性,不適用于HTTP/1.0,在緩存未失效前,得不到修改后的資源
-
-
Expires(時間)
-
GMT時間
服務端和客戶端的時間不一致會出現問題,適用于HTTP/1.0和HTTP/1.1,在緩存未失效前,得不到修改后的資源
-
1.1.2 協商緩存
當第一次請求時服務器返回的響應頭中沒有Cache-Control和Expires或者Cache-Control和Expires過期,也或者他的屬性設置為no-cache(不走強緩存),那么瀏覽器第二次請求時就會與服務器進行協商,與服務器對比判斷資源是否進行了更新。如果服務器端的資源沒有修改,那么就會返回304,告訴瀏覽器可以使用緩存中的數據,這樣就減少了服務器的傳輸壓力。如果數據有更新服務器就會返回200狀態碼,服務器就會返回更新后的資源并且將緩存信息一起返回。
-
ETag/If-Not-Match(HTTP/1.1)
-
校驗值
默認使用hash算法,在分布式環境下可能會出現不同服務器生成的ETag值不一致;精確的判斷資源有無被修改,可識別一秒內的修改次數;計算ETag需要性能消耗
-
-
Last-Modified/If-Modified-Since(HTTP/1.0)
-
GMT時間
只要資源修改,無論內容有無變化,都會將資源返回客戶端;以時刻為標識,無法獲取一秒內的修改變化;某些服務器不能準確獲取最后的修改時間
-
當瀏覽器第一次向服務器發送請求時,會在響應頭中返回協商緩存頭的屬性:ETag和Last-Modified,其中ETag返回的是一個hash值,Last-Modified返回的是GMT格式的最后修改時間。瀏覽器第二次發送請求時,會在請求頭中帶上與ETag對應的If-Not-Match,這個值就是響應頭中返回的ETag的值,Last-Modified對應If-Modified-Since。服務器在接收到這兩個參數后會進行比較,如果返回304,則說明請求資源沒被修改,瀏覽器可以直接在緩存中獲取數據,否則服務器會直接返回數據。
ETag/If-Not-Match是在HTTP/1.1出現的,主要是解決以下問題:
(1)、Last-Modified標注的最后修改只能精確到秒級,如果某些文件在1秒鐘以內,被修改多次的話,它將不能準確標注文件的修改時間
(2)、如果某些文件被修改了,但是內容并沒有任何變化,而Last-Modified卻改變了,導致文件沒法使用緩存
(3)、有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形
2.1 如何使用HTTP緩存?
一般需要緩存的資源有html頁面和其他靜態資源:
-
html
html頁面緩存設置主要是在head標簽中嵌入meta標簽,這種方式只對頁面有效,對頁面上的資源無效
-
禁用緩存
-
IE瀏覽器才識別的標簽,不一定會在請求字段加上Pragma,但的確會讓當前頁面每次都發新請求
<meta http-equiv="pragma" content="no-cache"> -
其他主流瀏覽器識別的標簽
<meta http-equiv="cache-control" content="no-cache"> -
IE瀏覽器才識別的標簽,該方式僅僅作為知會IE緩存時間的標記,你并不能在請求或響應報文中找到Expires字段
<meta http-equiv="expires" content="0">
-
-
設置緩存
-
僅有IE瀏覽器才識別的標簽
<meta http-equiv="Expires" content="Mon, 20 Aug 2018 23:00:00 GMT" /> -
其他主流瀏覽器識別的標簽
<meta http-equiv="Cache-Control" content="max-age=7200" />
-
-
-
靜態資源
靜態資源的緩存一般是在web服務器上配置,例如nginx,Apache。
2.2 注意點
強緩存情況下,只要緩存還沒過期,就會直接從緩存中取數據,就算服務器端有數據變化,也不會從服務器端獲取了,這樣就無法獲取到修改后的數據。決解的辦法有:在修改后的資源加上隨機數,確保不會從緩存中取。
盡量減少304的請求,因為我們知道,協商緩存每次都會與后臺服務器進行交互,所以性能上不是很好。從性能上來看盡量多使用強緩存。
更多詳細的內容可以看看這位大佬寫的文章
總結
以上是生活随笔為你收集整理的前端缓存之HTTP缓存(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(730):函数的概念
- 下一篇: 前端学习(1328):服务器基础概念