清除浏览器缓存之后为什么还是显示旧的html页面_Web缓存控制策略详解
管理Web緩存的最常用和最有效的方法之一是通過Cache-Control HTTP標頭,由于此標頭適用于Web頁面的緩存,這意味著我們頁面上的所有內容都可以具有非常精細化的緩存策略。通過各種自定義策略,我們控制的策略就可以變得非常復雜和強大。
Cache-Control
管理Web緩存的最常用和最有效的方法之一是通過Cache-Control HTTP標頭,由于此標頭適用于Web頁面的緩存,這意味著我們頁面上的所有內容都可以具有非常精細化的緩存策略。通過各種自定義策略,我們控制的策略就可以變得非常復雜和強大。
Cache-Control標頭可能如下所示:
Cache-Control: public, max-age=31536000Cache-Control是標頭,public和max-age=31536000都是指令。 Cache-Control標頭可以接受一個或多個指令,我想在本文中討論的就是這些指令,比如它們的真正含義以及它們的最佳用例。
public和private緩存
public意味著任何緩存都可以存儲響應的副本,其中就包括CDN、代理服務器等。public指令通常是多余的,因為其他指令(比如max-age)的存在是隱式指令,緩存可能會存儲一個副本。
另一方面,private是一個顯式指令,只有響應的最終接收者(客戶端或瀏覽器)才可以存儲該文件的副本。雖然private本身不是具有安全功能,但是它的目的是防止public緩存(例如CDN)存儲包含一個用戶唯一信息的響應。
max-age
max-age定義了一個以秒為單位的時間單位(相對于請求的時間),該單位的響應被認為是‘fresh’。
Cache-Control: max-age=60此Cache-Control標頭會告訴瀏覽器,它可以在接下來的60秒內使用緩存中的此文件,而不必擔心重新被驗證。 不過60秒后,瀏覽器將返回服務器以重新驗證文件。
如果服務器有一個新文件供瀏覽器下載,它將以200響應進行響應,下載新文件后,舊文件將從HTTP緩存中彈出,新文件將替換它,并將成為新的緩存標頭。
如果服務器沒有需要下載的更新副本,則服務器將以200響應進行響應,不需要下載任何新文件,并將使用新的標頭更新緩存副本。這意味著,如果仍然存在Cache-Control:max-age = 60標頭,則緩存文件在60秒后將再次啟動。算下來,一個文件的總緩存時間為120秒。
注意:max-age會有自動警告的屬性,如果瀏覽器過于陳舊,則max-age會提醒用戶,但用戶可以選擇忽略此警告。瀏覽器可能會使用自己的試探法來決定是否在不重新驗證文件的情況下發布文件的陳舊副本。這種行為有些不確定,所以很難確切地知道瀏覽器將實際做什么。為此,我們有一系列顯式指令,可以用它們來擴充max-age。
s-maxage
s-maxage將優先于max-age指令,但僅限在共享緩存的上下文中使用。將max-age和s-maxage結合使用,你可以分別為private和public緩存(例如代理、CDN)提供不同的啟動時間。
no-store
Cache-Control: no-store如果我們不想緩存文件怎么辦?如果文件包含敏感信息怎么辦?也許這是一個包含銀行詳細信息的HTML頁面?或許這些信息對時間至關重要?也許是一個包含實時股票價格的頁面?其實我們并不想在緩存中存儲或提供任何類似的響應:我們總是希望丟棄敏感信息并獲取最新的實時信息。這時,我們就要用到no-store指令。
no-store是一個非常強大的指令,不會將任何信息保存到任何緩存中,無論是private或其他緩存。
no–cache
Cache-Control: no-cache這是讓大多數人誤解的指令,no – cache存并不意味著“沒有緩存”。這只是意味著“在你使用服務器重新驗證緩存之前,不需要從緩存中提供副本就可以使用以前的緩存副本”。
no-cache實際上是一種非常聰明的緩存更新策略,這樣就可以始終保證最新的緩存副本。除非服務器響應更快,否則no-cache將始終must-revalidate服務器才能釋放瀏覽器的緩存副本,但如果服務器響應速度一般,網絡傳輸只有一個文件的標頭,則可以直接從緩存中抓取正文而不是重載。
因此,這是一種結合更新策略,并快速從緩存中獲取文件的智能方法,但前提是它至少要獲得一個HTTP標頭響應。
無緩存的一個很好的用例幾乎就是動態HTML頁面,想想新聞網站的主頁:它不是實時的,也不包含任何敏感信息,但理想情況下我們希望頁面始終顯示最新鮮的內容。我們可以使用cache-control:no-cache來指示瀏覽器首先檢查服務器,如果服務器沒有更新的東西(304),就會重用緩存的版本。如果服務器確實有一些更新鮮的內容,它會響應(200)并發送更新的文件。
提示:沒有必要發送max-age指令和no-cache指令,因為重新驗證的時間限制為零秒。
must-revalidate
更令人困惑的是,盡管上面的代碼聽起來應該稱為must-revalidate,但事實證明,must-revalidate仍然具有自己的特點。
Cache-Control: must-revalidate, max-age=600must-revalidate需要一個相關的max-age指令,如上所示,我們把它設置為十分鐘。此時,no-cache將立即與服務器重新驗證,只有在服務器允許時才使用緩存副本時,must-revalidate才類似于一個寬限期no-cache。具體過程是這樣的,在前十分鐘,瀏覽器不會與服務器重新驗證,但十分鐘過后,它又返回服務器。如果服務器沒有任何新內容,它將以304響應并且新的Cache-Control標頭應用于緩存文件。然后再以十分鐘為單位,如果在十分鐘之后,服務器上有一個較新的文件,我們會收到200響應及其正文,并且本地緩存會更新。
proxy-revalidate
與s-maxage類似,proxy-revalidate是must-revalidate的public緩存的自定義版本,它只是被private緩存忽略了。
immutable
immutable是一個非常新的且非常簡潔的指令,它告訴瀏覽器關于我們發送的文件類型的更多信息,該指令可以解決以下問題:用戶刷新會導致瀏覽器重新驗證文件,無論其新鮮度如何,用戶刷新通常意味著以下任意情況必定發生:頁面看起來不完整或者內容還和原來一樣。
所以,我們有必要檢查服務器上是否有更新的內容。
如果服務器上有更新的文件,我們肯定希望下載它。因此,我們將得到200響應,即一個新文件出現。但是,如果服務器上沒有新文件,我們將得到304響應,即沒有新文件,如果是專業,則整個延遲反應就沒有意義了。如果我們重新驗證許多導致延遲反應304的文件,可能會增加數百毫秒不必要的等待。
immutable是一種告訴瀏覽器文件有無可變內容的指令,如果內容無更新,則永遠不會重新驗證緩存。這樣,就可以完全消除延遲時間。不過,immutable所指的可變或不可變文件的具體含義是什么?
style.css:當我們更改此文件的內容時,即使根本不更改其名稱,這個文件也被認為是可變的。
style.ae3f66.css:這個文件是唯一的,它以基于其具體內容來命名的,所以一旦內容發生變化,我們就會得到一個全新的文件,此時,這個文件就被認為是不可變的。
我們將在Cache Busting部分中更詳細地討論這個問題。
如果我們能夠以某種方式向瀏覽器發出文件是不可變的信號,則它就不需要檢查更新版本,這正是immutable指令的作用:
Cache-Control: max-age=31536000, immutable
在支持immutable指令的瀏覽器中,用戶刷新永遠不會在31536000秒的新鮮度生命周期內進行重新驗證。這意味著無需花費不必要的延遲時間來檢索304響應,這可能會在關鍵路徑(CSS blocks rendering)上節省大量的延遲時間。
注意:你不應該將immutable應用于任何不可變的文件,因為你還應該有一個非常強大的緩存破壞策略。
stale-while-revalidate
到目前為止,我們已經談了很多關于重新驗證的內容,都是關于瀏覽器返回服務器以檢查是否有更新的文件的過程。在高延遲連接上,重新驗證的持續時間會很長,并且這個時間是固定的,直到我們對服務器進行額外的命令,否則既不能釋放緩存副本(304)也不能下載新文件(200)。
stale-while-revalidate提供的是寬限期,在此期間,當我們檢查新版本時,允許瀏覽器使用過去的緩存。
Cache-Control: max-age=31536000, stale-while-revalidate=86400該指令是在告訴瀏覽器“這個文件可以使用一年,一年之后,還可以再用一個星期。在這時候,如果你要繼續使用這個舊的資源,就必須在后臺重新驗證它”。
stale-while-revalidate對非關鍵資源是一個很好的指令,當然,我們希望使用最新的版本。但是我們知道,如果在檢查更新時再次使用過時的響應,不會造成任何對更新的破壞。
stale-if-error
與stale-while-revalidate類似,如果重新驗證的資源返回5xx類錯誤,stale-if-error允許瀏覽器有一段緩沖時間,在此期間可以允許返回過時的響應。
Cache-Control: max-age=2419200, stale-if-error=86400在本文中,我們指定了28天(2419200秒)以內的緩存文件都是新的,如果我們在那之后遇到更新錯誤,我們會多追加一天(86400秒),在此期間我們將允許過時的資源響應。
Cache Busting(緩存破壞)
只討論緩存得正常情況而不討論緩存破壞的情況是不負責任的。在考慮你的緩存策略之前,我總是建議你解決緩存破壞策略。因為當開發者修改了網站就會發生問題,因為用戶本地緩存的文件還是老文件。這樣用戶看到的不僅還是舊的功能,如果網站緩存了css和js文件,它們還在引用不存在的元素或者被移除的被重命名的元素,網站就會報錯破壞。
Cache busting就是強制瀏覽器下載新文件的一種方法,通過將新文件的名字修改成和舊文件不同的名字即可實現。
No Cache Busting – style.css
這是最不可取的做法:絕對沒有任何緩存破壞。這是一個可變文件,我們真的很難實現Cache Busting。
你應該非常謹慎地緩存這些文件,因為一旦它們出現在用戶的設備上,我們幾乎失去了對它們的所有控制權。
盡管這個例子是一個樣式表,但HTML頁面正好就是這個特性。由于我們無法更改網頁的文件名,網站就會報錯破壞!這正是我們根本不會緩存它們的原因。
Query String – style.css?v=1.2.14
此時,我們仍然有一個可變文件,但我們在其文件路徑中添加了一個查詢字符串。雖然這比什么都不做要好,但它仍然不完美。如果要刪除查詢字符串,我們會回到之前的類別,即完全不存在緩存破壞。許多代理服務器和CDN都不會通過配置來緩存任何帶有查詢字符串的內容。例如,來自Cloudflare的文檔, “style.css?something”的請求將被標準化為“style.css”,或查詢字符串可能包含特定于一個特定響應的信息。
Fingerprint – style.ae3f66.css
到目前為止,指紋識別是緩存破壞文件的首選方法。每次文件的內容發生變化時,我們都對其進行更改,這并不會緩存任何內容。這意味著,我們將最終得到的是一個全新的文件!且該文件不可更改。如果你可以在靜態緩存上實現此功能,請執行此操作!一旦你成功地實現了這個非常可靠的緩存破壞策略,你就能得到最強的緩存控制指令了:
Cache-Control: max-age=31536000, immutable實施細節
此方法的關鍵是更改文件名,但不一定是對指紋進行更改。以下所有示例都具有相同的效果:
- /assets/style.ae3f66.css:使用文件內容的哈希產生破壞;
- /assets/style.1.2.14.css:使用一個已發布的版本產生破壞;
- /assets/1.2.14/style.css:通過更改URL中的目錄產生破壞;
但是,最后一個示例表明,我們對每個版本而不是每個單獨的文件進行版本控制。這反過來意味著,如果我們只需要緩存樣式表,則還必須緩存該版本的所有靜態文件,所以首選選項是前兩個。
Clear-Site-Data
目前我們正在開發一個規范,以幫助開發人員確定整個緩存的來源,并從根上徹底一次性清除,這就是Clear-Site-Data的含義,它讓Web開發人員對瀏覽器本地存儲的數據有更多控制能力。
我不想在這篇文章中詳細介紹Clear-Site-Data,它不是Cache-Control指令,而是一個全新的HTTP標頭文件。
Clear-Site-Data: "cache"將此標頭應用于你的任何一個源緩存都將讓整個源的緩存破壞,而不僅僅是它所附加的文件。這意味著,如果你需要從所有訪問者的緩存中強制破壞整個站點,則可以將上述標頭應用于HTML有效內容。
在撰寫本文時,僅支持瀏覽器有Chrome,Android Webview,Firefox和Opera。
提示:Clear-Site-Data將接受許多指令:“cookies”,“storage”,“executionContexts”和“*” (當然,“*”的意思是“以上所有”)。
具體示例
好的,讓我們來看看一些應用場景以及我們可能采用哪種Cache-Control標頭。
網上銀行頁面
Request URL: /account/ Cache-Control: no-store根據規范,這足以阻止瀏覽器在private和共享緩存中持續對磁盤的響應。
no-store響應指令會命令緩存不得存儲立即請求或響應的任何部分,此指令適用于private和共享緩存。 “不得存儲”意味著緩存不得故意將信息存儲在非易失性存儲中,并且必須盡最大努力盡快在轉發后從易失性存儲中刪除所存儲的信息。
但如果你想要防止緩存的發生,你可以選擇:
Request URL: /account/ Cache-Control: private, no-cache, no-store該指令將明確指示不要在public緩存(例如CDN)中存儲任何內容,以始終提供最新的副本。
列車時間表網頁
如果我們正在構建一個顯示實時信息的頁面,則希望保證用戶始終能夠看到最新的信息。此時,可以使用以下指令:
Request URL: /live-updates/ Cache-Control: no-cache這個簡單的指令意味著瀏覽器不會直接從緩存中顯示響應,意味著頁面不會顯示過時的列車信息。
FAQ頁面
像FAQ這樣的頁面可能很少更新,因為其中的內容大多都是常識性問題,對時效性沒有要求。我們可能會暫時緩存這樣的HTML頁面,并強制瀏覽器定期檢查新內容,而不是每次對緩存進行訪問。可以使用以下指令:
Request URL: /faqs/ Cache-Control: max-age=604800, must-revalidate該指令會告訴瀏覽器將HTML頁面緩存一周(604800秒),并且一周結束后,我們需要檢查服務器是否有更新。
頁面中的圖片
頁面中的圖片通常都是一篇文章的配圖,通常我們都會下載下來,所以我們想緩存它。但其實它對頁面的更新狀態并不會產生影響,因此我們不需要它的更新狀態。可以使用以下指令:
Request URL: /content/masthead.jpg Cache-Control: max-age=2419200, must-revalidate, stale-while-revalidate=86400該指令會告訴瀏覽器將圖像存儲28天(2419200秒),我們要在28天的時間限制后檢查該圖像在服務器中是否有更新。
總結
1.判斷是否設置了cacheBusting屬性非常重要。在開始執行緩存策略之前,請先制定緩存破壞策略。
2.一般來說,緩存HTML內容是一個錯誤的方法。 由于HTML網址不能被破壞,并且由于你的HTML頁面通常是其余子資源的入口點,因此你最終也會緩存對靜態資源的引用。
3.如果要緩存任何HTML,在站點上的不同類型的HTML頁面上使用不同的緩存策略可能會導致不一致,比如有的頁面總是最新的內容,而其他頁面的內容有時是從緩存中獲取的。
4.如果你能夠可靠的緩存(使用指紋)的靜態資產,那么你還不如一次性使用一個不可變的指令緩存數年,以便更好地進行管理。
5.非關鍵緩存內容可以使用stale-while-revalidate等指令,增加緩存的寬限期。
6.immutable和stale-while-revalidate不僅為我們提供了緩存的傳統優勢,而且還允許我們在重新驗證時降低延遲。
7.充分了解你的緩存,并設計具有針對性的緩存策略。
天下數據IDC與全球近120多個國家頂級機房直接合作,包括香港、美國、韓國、日本、臺灣、新加坡、荷蘭、法國、英國、德國、埃及、南非、巴西、印度、越南等國家和地區的服務器、云服務器的租用服務!
總結
以上是生活随笔為你收集整理的清除浏览器缓存之后为什么还是显示旧的html页面_Web缓存控制策略详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抖音音浪可以换多少钱 抖音音浪能换多少钱
- 下一篇: 安卓手机浏览器排行_5g时代已来临!五月