1、前言作為一個前端,了解http緩存是非常必要,它不僅是面試的必要環(huán)節(jié),也更是實戰(zhàn)開發(fā)中必不可少需要了解的知識點,本文作者將從緩存的概念講到如何在業(yè)務中設計一個合理的緩存架構,帶你一步一步解開http緩存的神秘面紗。 2、http緩存定義當客戶端向服務器請求資源時,會先抵達瀏覽器緩存,如果瀏覽器有“要請求資源”的副本,就可以直接從瀏覽器緩存中提取而不是從原始服務器中提取這個資源。http緩存一般針對GET請求,POST請求一般不會緩存,因為POST請求執(zhí)行的任務都是對服務器產生副作用或者非冪等性的任務,既然要改變服務器資源,自然請求是要進入服務器進行處理的。緩存帶來的好處是巨大的,減少了http請求,自然也就減少的服務端壓力,并且增加了資源的訪問速度,但是胡亂使用緩存,將會帶來資源的不及時更新,甚至資源更新錯位,災難也是巨大的。 3、強緩存3.1、強緩存定義如果命中緩存,直接從緩存中拿數(shù)據(jù),請求不會經過服務器,返回的http狀態(tài)碼為200(from disk cache) 下面給一張流程圖來說明強緩存的請求過程,為了方便假設瀏覽器存在一個緩存數(shù)據(jù)庫(其實就是disk磁盤,緩存數(shù)據(jù)存放的地方)。 仔細看上面的流程圖,強緩存的最大特點就是在命中緩存的情況下不會經過服務器,而是直接返回。 3.2、Http頭Expires/Cache-Control設置強緩存Cache-Control里面存在多個屬性來控制緩存,設置強緩存即設置資源的有效期,屬性為max-age. app.get('/script1.js', function (req, res, next) { // res.header('Cache-Control', 'must-revalidate, max-age=600') // res.header('Content-Type', 'text/html') res.header('Cache-Control', 'max-age=20') res.sendFile(__dirname + '/script.js')}) Expires和max-age都是用于控制緩存的生命周期。不同的是Expires指定的是過期的具體時間,例如Sun, 21 Mar 2027 08:52:14 GMT,而max-age指定的是生命時長秒數(shù)315360000。 4、協(xié)商/對比緩存4.1、定義協(xié)商緩存與強制緩存的不同之處在于,協(xié)商緩存每次讀取數(shù)據(jù)時都需要跟服務器通信,并且會增加緩存標識。在第一次請求服務器時,服務器會返回資源,并且返回一個資源的緩存標識,一起存到瀏覽器的緩存數(shù)據(jù)庫。當?shù)诙握埱筚Y源時,瀏覽器會首先將緩存標識發(fā)送給服務器,服務器拿到標識后判斷標識是否匹配,如果不匹配,表示資源有更新,服務器會將新數(shù)據(jù)和新的緩存標識一起返回到瀏覽器;如果緩存標識匹配,表示資源沒有更新,并且返回 304 狀態(tài)碼,瀏覽器就讀取本地緩存服務器中的數(shù)據(jù)。 再次訪問: 還是給一張流程圖來說明。(圖是盜的,協(xié)商緩存也可以成為對比緩存,圖中的對比緩存就是協(xié)商緩存) 4.2、協(xié)商緩存如何驗證第一次請求將response header的Last-Modified和Etag存起來,在第二次請求通過request header的If-Modified-Since和If-None-Match傳到服務端進行驗證,如果命中緩存,返回304,不帶返回的數(shù)據(jù),瀏覽器自動從緩存中獲取數(shù)據(jù)資源,若未命中緩存返回200,帶上數(shù)據(jù)資源。 ** Last-Modified:** ** If-Modified-Since:** ** Etag / If-None-Match(優(yōu)先級高于Last-Modified / If-Modified-Since) ** ** If-None-Match:** 4.3、Http頭如何設置協(xié)商緩存在強緩存那一節(jié)說到使用Cache-Control的max-age來設置資源過期時間,那么當max-age=0的時候呢,自然瀏覽器第一時間發(fā)現(xiàn)資源過期,request header就會帶著If-Modified-Since和If-None-Match去服務端驗證。
就可以觸發(fā)協(xié)商緩存了,其實Cache-Control中還有兩個屬性都可以設置協(xié)商緩存 must-revalidate和no-cache Cache-Control: must-revalidate, max-age=600 該頭信息意義就是在資源有效期過后必須進行驗證, 與只設置max-age=600的區(qū)別是,前面一個是MUST,而后面一個是SHOULD,理論上來說它們的效果是一致的。
如果要不緩存,每次都請求新的資源應該使用 Cache-Control: no-store 5、關于緩存的Http頭總結5.1、'no-cache', 'no-store', 'must-revalidate'Cache-Control字段可以設置的不僅僅是max-age存儲時間,還有其他額外的值可以填寫,甚至可以組合。主要使用的值有如下: 5.2、Expires VS. max-ageExpires和max-age都是用于控制緩存的生命周期。不同的是Expires指定的是過期的具體時間,例如Sun, 21 Mar 2027 08:52:14 GMT,而max-age指定的是生命時長秒數(shù)315360000。 5.3、Etag VS. Last-ModifiedEtag和Last-Modified都可以用于對資源進行驗證,而Last-Modified顧名思義,表示資源最后的更新時間。 5.4、max-age=0 VS. no-cachemax-age=0是在告訴瀏覽器,資源已經過期了,你應該(SHOULD)對資源進行重新驗證了;而no-cache則是告訴瀏覽器在每一次使用緩存之前,你必須(MUST)對資源進行重新驗證。 5.5、public VS. private要知道從服務器到瀏覽器之間并非只有瀏覽器能夠對資源進行緩存,服務器的返回可能會經過一些中間(intermediate)服務器甚至甚至專業(yè)的中間緩存服務器,還有CDN。而有些請求返回是用戶級別、是私人的,所以你可能不希望這些中間服務器緩存返回。此時你需要將Cache-Control設置為private以避免暴露。 6、緩存實戰(zhàn)前面寫了很多緩存的基礎知識,那么如何設計一個可靠的緩存規(guī)則,這個其實得根據(jù)你的實際需求而定。
其他的資源可根據(jù)下面這張決策樹來進行設置 7、memory cache“內存緩存”中主要包含的是當前文檔中頁面中已經抓取到的資源。例如頁面上已經下載的樣式、腳本、圖片等。我們不排除頁面可能會對這些資源再次發(fā)出請求,所以這些資源都暫存在內存中,當用戶結束瀏覽網(wǎng)頁并且關閉網(wǎng)頁時,內存緩存的資源會被釋放掉。 8、瀏覽器可能會限制Cache-Control頭無效Linux公社的RSS地址:https://www./rssFeed.aspx 本文永久更新鏈接地址:https://www./Linux/2019-08/160265.htm |
|