出處:
通過internet獲取資源既緩慢,成本又高。為此,http協議裡包含了控制快取的部分,以使http客戶端可以快取和重用以前獲取的資源,從而優化效能,提公升體驗。雖然http中關於快取控制的部分,隨著協議演進,有一些變化。但我覺著,作為後端程式設計師,在開發web服務時,只需要關注請求頭if-none-match、響應頭etag、響應頭cache-control就足夠了。因為這三個http頭就可以滿足你的需求,並且,當今絕大多數的瀏覽器,都支援這三個http頭。我們所要做的就是,確保每個伺服器響應都提供正確的 http 頭指令,以指導瀏覽器何時可以快取響應以及可以快取多久。
上圖中有三個角色,瀏覽器、web**和伺服器,如圖所示http快取存在於瀏覽器和web**中。當然在伺服器內部,也存在著各種快取,但這已經不是本文要討論的http快取了。所謂的http快取控制,就是一種約定,通過設定不同的響應頭cache-control來控制瀏覽器和web**對快取的使用策略,通過設定請求頭if-none-match和響應頭etag,來對快取的有效性進行驗證。
etag全稱entity tag,用來標識乙個資源。在具體的實現中,etag可以是資源的hash值,也可以是乙個內部維護的版本號。但不管怎樣,etag應該能反映出資源內容的變化,這是http快取可以正常工作的基礎。
如上例中所展示的,伺服器在返回響應時,通常會在http頭中包含一些關於響應的元資料資訊,其中,etag就是其中乙個,本例中返回了值為x1323ddx的etag。當資源/file的內容發生變化時,伺服器應當返回不同的etag。
對於同乙個資源,比如上一例中的/file,在進行了一次請求之後,瀏覽器就已經有了/file的乙個版本的內容,和這個版本的etag,當下次使用者再需要這個資源,瀏覽器再次向伺服器請求的時候,可以利用請求頭if-none-match來告訴伺服器自己已經有個etag為x1323ddx的/file,這樣,如果伺服器上的/file沒有變化,也就是說伺服器上的/file的etag也是x1323ddx的話,伺服器就不會再返回/file的內容,而是返回乙個304的響應,告訴瀏覽器該資源沒有變化,快取有效。
如上例中所示,在使用了if-none-match之後,伺服器只需要很小的響應就可以達到相同的結果,從而優化了效能。
每個資源都可以通過http頭cache-control來定義自己的快取策略,cache-control控制誰在什麼條件下可以快取響應以及可以快取多久。 最快的請求是不必與伺服器進行通訊的請求:通過響應的本地副本,我們可以避免所有的網路延遲以及資料傳輸的資料成本。為此,http 規範允許伺服器返回一系列不同的 cache-control 指令,控制瀏覽器或者其他中繼快取如何快取某個響應以及快取多長時間。
cache-control 頭在 http/1.1 規範中定義,取代了之前用來定義響應快取策略的頭(例如 expires)。當前的所有瀏覽器都支援 cache-control,因此,使用它就夠了。
以下我來介紹可以再cache-control中設定的常用指令。
該指令指定從當前請求開始,允許獲取的響應被重用的最長時間(單位為秒。例如:cache-control:max-age=60表示響應可以再快取和重用 60 秒。需要注意的是,在max-age指定的時間之內,瀏覽器不會向伺服器傳送任何請求,包括驗證快取是否有效的請求,也就是說,如果在這段時間之內,伺服器上的資源發生了變化,那麼瀏覽器將不能得到通知,而使用老版本的資源。所以在設定快取時間的長度時,需要慎重。
如果設定了public,表示該響應可以再瀏覽器或者任何中繼的web**中快取,public是預設值,即cache-control:max-age=60等同於cache-control:public, max-age=60。
在伺服器設定了private比如cache-control:private, max-age=60的情況下,表示只有使用者的瀏覽器可以快取private響應,不允許任何中繼web**對其進行快取 – 例如,使用者瀏覽器可以快取包含使用者私人資訊的 html 網頁,但是 cdn 不能快取。
需要注意的是,no-cache這個名字有一點誤導。設定了no-cache之後,並不是說瀏覽器就不再快取資料,只是瀏覽器在使用快取資料時,需要先確認一下資料是否還跟伺服器保持一致。如果設定了no-cache,而etag的實現沒有反應出資源的變化,那就會導致瀏覽器的快取資料一直得不到更新的情況。
如果伺服器在響應中設定了no-store即cache-control:no-store,那麼瀏覽器和任何中繼的web**,都不會儲存這次相應的資料。當下次請求該資源時,瀏覽器只能重新請求伺服器,重新從伺服器讀取資源。
max-age
該指令指定從當前請求開始,允許獲取的響應被重用的最長時間(單位為秒。例如:cache-control:max-age=60表示響應可以再快取和重用 60 秒。需要注意的是,在max-age指定的時間之內,瀏覽器不會向伺服器傳送任何請求,包括驗證快取是否有效的請求,也就是說,如果在這段時間之內,伺服器上的資源發生了變化,那麼瀏覽器將不能得到通知,而使用老版本的資源。所以在設定快取時間的長度時,需要慎重。
public和private
如果設定了public,表示該響應可以再瀏覽器或者任何中繼的web**中快取,public是預設值,即cache-control:max-age=60等同於cache-control:public, max-age=60。
在伺服器設定了private比如cache-control:private, max-age=60的情況下,表示只有使用者的瀏覽器可以快取private響應,不允許任何中繼web**對其進行快取 – 例如,使用者瀏覽器可以快取包含使用者私人資訊的 html 網頁,但是 cdn 不能快取。
no-cache
需要注意的是,no-cache這個名字有一點誤導。設定了no-cache之後,並不是說瀏覽器就不再快取資料,只是瀏覽器在使用快取資料時,需要先確認一下資料是否還跟伺服器保持一致。如果設定了no-cache,而etag的實現沒有反應出資源的變化,那就會導致瀏覽器的快取資料一直得不到更新的情況。
no-store
如果伺服器在響應中設定了no-store即cache-control:no-store,那麼瀏覽器和任何中繼的web**,都不會儲存這次相應的資料。當下次請求該資源時,瀏覽器只能重新請求伺服器,重新從伺服器讀取資源。
寫給後端程式設計師的HTTP快取原理介紹
通過internet獲取資源既緩慢,成本又高。為此,http協議裡包含了控制快取的部分,以使http客戶端可以快取和重用以前獲取的資源,從而優化效能,提公升體驗。雖然http中關於快取控制的部分,隨著協議演進,有一些變化。但我覺著,作為後端程式設計師,在開發web服務時,只需要關注請求頭if non...
寫給後端程式設計師的HTTP快取原理介紹
通過internet獲取資源既緩慢,成本又高。為此,http協議裡包含了控制快取的部分,以使http客戶端可以快取和重用以前獲取的資源,從而優化效能,提公升體驗。雖然http中關於快取控制的部分,隨著協議演進,有一些變化。但我覺著,作為後端程式設計師,在開發web服務時,只需要關注請求頭if non...
寫給未來的程式設計師
寫給未來的程式設計師 l 不要死記語法 很多初學者試圖把各種語法背下來,其實這是極其錯誤的,程式開發的語法,規範特別多,不可能都記得下來,你只要知道有這麼乙個功能就可以了,需要時候翻閱書籍,或者找幫助檔案,這樣省時省力。l 多動手,多練習 只知道死啃書本的人,是不會成為開發高手的,只有多上機編寫程式...