測試同窗:你問題改了嘛?我怎麼沒看到效果啊?前端
前端同窗:我改了啊,可能有緩存吧,清一下緩存試試(心裏os:難道是我寫的代碼有問題?🤔🤔🤔)。nginx
首先說下爲何須要緩存?面試
如今的前端頁面已經不是刀耕火種時代的效果了,隨便打開一個頁面都能看到各類炫酷的交互效果。像如今各類電商的促銷活動:618,雙11,雙12🛒🛒🛒。每個活動對於服務器都是一個巨大的挑戰,就拿一個圖片來講,若是每一個用戶每次訪問這個頁面都要去服務器拿新的資源的話,服務器應該早就崩潰了😵😵😵。chrome
瀏覽器的緩存主要是遵循http緩存機制,主要分爲兩種緩存:瀏覽器
強緩存包括:Pragma,Expires,Cache-Control緩存
首先解釋下什麼是強緩存bash
強緩存是表明瀏覽器進行一次請求後,把請求的文件放在內存或者硬盤中,有的時候咱們會在狀態碼中看到from memory cache
或者from disk cache
,這時候其實表明咱們命中了強緩存,此時並無發生瀏覽器發送請求的行爲。服務器
memory cache 跟disk cache的區別測試
現代瀏覽器通常都是基於HTTP/1.1的。 因爲 Pragma 在 HTTP 響應中的行爲沒有確切規範,因此不能可靠替代 HTTP/1.1 中通用首部 Cache-Control,儘管在請求中,假如 Cache-Control 不存在的話,它的行爲與 Cache-Control: no-cache 一致,建議只在須要兼容 HTTP/1.0 客戶端的場合下應用 Pragma 首部。網站
Pragma: no-cache
複製代碼
做用是強制要求緩存服務器在返回緩存的版本以前將請求提交到源頭服務器進行驗證。
先來看下它的設置參數:
expires:10s/10m/10h/10d; //分別對應:秒,分,時,天
複製代碼
Expires的值爲服務器返回的規定該資源的到期時間,在下一次瀏覽器請求時會拿本地時間對比這個服務器返回的時間,若是沒有過時則直接可使用緩存數據,無需再發起請求。
這時候問題來了,本地的時間是能夠修改的
一方面對比的是本地的時間會有必定的偏差;另外一方面如今瀏覽器基本都是基於http1.1版本的,Expires是http1.0版本的產物,這個時候就出現了它的替代品Cache-Control。
咱們先來看下它的經常使用參數都有哪些:
參數 | 含義 |
---|---|
max-age | 單位是秒,失效的時間 |
no-cache | 強制要求緩存把請求提交給原始服務器進行驗證 |
no-store | 緩存不該存儲有關客戶端請求或服務器響應的任何內容 |
public | 存在響應頭中,表示能夠被任何對象緩存 |
private | 存在響應頭中,表示只能被單個用戶緩存,不能做爲共享緩存 |
指令不區分大小寫,多個指令以逗號分隔,Cache-Control比Expires的優先級要高。
no-cache跟no-store傻傻分不清楚
首先cache-control是一個通用消息頭字段,就是說請求頭跟響應頭均可以加入這個字段,可是在不一樣的位置意思是不一樣的:
協商緩存包括:Last-Modified/If-Modified-Since,Etag/If-None-Match
什麼叫協商緩存?
當瀏覽器檢查強緩存過時後,因而發送請求到服務器,這時候服務器並不會直接去拿新的資源,而是要檢查請求頭部是否有緩存標識If-Modified-Since
或者If-None-Match
,判斷成功後則返回304 Not Modified
,通知客戶端可使用緩存的數據。
對於協商緩存,在相對高的nginx版本里面,會自動給客戶端返回Last-Modified跟Etag。客戶端在下次請求一樣的url時,根據HTTP協議的規定,會帶上If-Modified-Since報頭,值爲上次服務器返回的Last-Modified值;同時也會帶一個If-None-Match報頭,值爲上次服務器返回的Etag值。咱們能夠在Response Headers 跟 Request Headers 中查看參數。
Last-Modified是存在於響應頭部,包含源頭服務器認定的資源作出修改的日期及時間。它一般被用做一個驗證器來判斷接收到的或者存儲的資源是否彼此一致。相對應的If-Modified-Since存在於請求頭部,它的值是上一次服務器返回的Last-Modified的值。
請求頭:
Etag存在於響應頭部的,是服務器資源的惟一標識符,至關於文件指紋,若是文件改變則這個值就會改變。相對應的If-Modified-Since存在於請求頭部,它的值是上一次服務器返回的Etag的值。
請求頭:
有Last-Modified爲何還須要Etag?
此處描述的是mac下的chrome,針對具體資源去訪問的結果,每一個版本的瀏覽器可能存在不一樣。
行爲一:
瀏覽器新開窗口的輸入url進行訪問,先檢查強緩存,若是命中Status Code會顯示 200 OK (from disk cache)
或者200 OK (from memory cache)
地址回車或者正常從新加載(command + r)會致使瀏覽器跳過檢查強緩存,直接去服務器檢查協商緩存,若是命中則Status Code會顯示304 Not Modified
。
行爲三:
硬性的從新加載行爲(command + shift + r)會致使瀏覽器跳過強緩存跟協商緩存,直接去請求新的資源文件,返回狀態碼200。
清空緩存並硬性從新加載。會致使瀏覽器把緩存清空掉,直接去請求資源,返回狀態碼200。
若是是對一個站點的訪問,頁面裏面包括靜態資源,則對這種靜態資源來講上述行爲一跟行爲二都先檢查強緩存再去檢查協商緩存,其餘行爲表現一致。
說一下控制檯中的Network選項下面的Disable cache選項
咱們都知道勾選中以後起到不使用緩存的效果,可是其實這個時候,並非把緩存刪掉了,而是選擇讓瀏覽器跳過全部的緩存策略,這時候瀏覽器會在請求頭上加一個參數:Cache-Control:no-cache
。若是把這個選項再放開的話仍是會應用緩存策略的,只不過針對具體資源的請求時,瀏覽器會選擇在請求頭部加上Cache-Control:max-age=0
來跳過強緩存,檢查協商緩存。
另外說一下判斷瀏覽器有沒有發送請求的方法,能夠看下控制檯的Waterfall部分:
request sent
指的是發送HTTP請求的時間,若是
值爲零或者是沒有這個字段,則表明沒有發送請求。
有時間再講解一下其餘字段的意思吧,謝謝!!⛽️⛽️⛽️