記得當年面試創新工場前端實習生時,面試官曾經給了我一個建議,讓我有空去了解一下瀏覽器緩存機制,頗有意思的。當時的我由於拿到了實習 offer 以後就把這句話忘在了腦後。直到校招季,就在面試即將結束的時候,面試官微笑着問我「能說一下瀏覽器緩存的知識嗎?」而後不負衆望,面試官笑容漸漸消失,回家後等了幾天收到了感謝信。
學習的過程就是從不會到會,花了一個小時時間拜讀網上的相關博客,終於對瀏覽器緩存有了初步認識,開篇文章記錄下來,加深學習印象,也分享給也許如今不明白可是立刻就要明白的你。html
通俗地講,瀏覽器緩存就是把曾經訪問過的資源拷貝一份副本存在瀏覽器中,當之後再次訪問該網站時會根據一系列判斷最終決定是從瀏覽器中直接將曾經存儲的副本拿出來仍是去服務器獲取。
那麼使用瀏覽器緩存的緣由也就很明顯了:前端
咱們能夠簡單思考一下,在什麼狀況下咱們會去直接使用瀏覽器緩存呢?
首先,咱們要有相應的緩存。
其次,咱們的緩存沒有過時。
(上面兩句是我不負責任的回答,具體流程請看下面)面試
這裏咱們借用網絡上的一張圖片來大概瞭解一下過程:
瀏覽器
當咱們第一次打開某網站時,咱們的本地是不存在相應的緩存的,因而咱們須要向服務器請求對應的資源,根據返回的內容,判斷是否將資源緩存在本地,最後將頁面呈現出來。緩存
當咱們再次訪問該網站時,咱們發現本地有相應的緩存,因而咱們先要判斷該緩存是否過時,若是沒有,則從緩存中讀取內容。若是過時,咱們會發送請求判斷是否使用該緩存,若是不使用,則向服務器請求資源,再根據狀況判斷是否更新本地緩存。服務器
根據上面大體的流程,咱們將要引出兩個很是重要的概念。網絡
用戶發送的請求,直接從客戶端緩存讀取,不發送請求到服務器,不與服務器發生交互行爲。學習
用戶發送的請求,發送到服務器後,由服務器判斷是否存緩存中獲取資源。若結果爲是,則返回 304 ;若不是,則返回 200 。網站
共同點:客戶端得到得數據都是從客戶端緩存中獲取。
不一樣點:強緩存不與服務器發生交互,而協商緩存須要與服務器交互。spa
咱們前面也簡單說了,所謂的「瀏覽器緩存」其實就是用戶的本地資源,不一樣瀏覽器的緩存文件地址也不相同。
通俗的講,判斷瀏覽器是否有緩存就是去判斷本地是否有對應的文件。
(這裏不做重點因此介紹的很是簡單,若有興趣可百度不一樣的瀏覽器緩存位置自行查看)
瀏覽器在對資源緩存事後,會將服務器端當時的 response header 保留下來,以下圖所示:
其中 Date 字段表示這次緩存時服務器的時間。
其中標紅的兩個字段是該過程的重點: Expires 和 Cache-Control
這是 HTTP1.0 中的標準,表示爲過時時間(服務器時間)
這是 HTTP1.1 中的標準,表示爲相對的過時時間。單位爲秒。有以下屬性:
咱們能夠發現, HTTP1.0 標準中的 Expires 存在一個問題:若是本地時間和服務器時間不一致,就會出現誤差。因而在 HTTP1.1 中使用了相對時間 Cache-Control 來彌補這個問題。
因而乎,判斷緩存是否過時的步驟就是:
這裏執行完畢後,若是判斷結果爲沒有過時,則使用客戶端緩存,也就是命中「強緩存」。
若是經過上述過程發現緩存過時了,這裏咱們就要與服務器協商是否使用緩存。
看上面的圖,這時咱們須要注意的是 ETag 和 Last-Modified 屬性:
資源的標識。每一個文件不相同,主要用於區分文件是否相同。
請求的資源上次的修改時間。
咱們會向服務器發送請求,若是上一次的緩存中存在以上兩個屬性,那麼瀏覽器會在 request header 中加入 If-Modified-Since (值爲 Last-modified 的值)和 If-None-Match (值爲 ETag 的值)。
這兩個值分別爲客戶端保留的資源上次修改時間和資源的標識。
若是沒有變化,則命中「協商緩存」,返回 304
以上就是瀏覽器緩存相關的入門知識,若是哪裏有描述不正確請及時告知我,很是感謝,同時但願這篇文章能對你有所幫助。
參考資料:
完全理解瀏覽器緩存機制
瀏覽器的協商緩存與強緩存