首先附上前面提到的一張圖:
根據(jù)上面的這張圖,來說http協(xié)議中的緩存,也就是cache-control將會格外清晰。
Cache-Control包括哪些特性呢光绕?
第一,可緩存性:public? private? no-cache畜份〉剩可緩存性指http的response進(jìn)過的哪些地方可以進(jìn)行緩存。public指在response返回經(jīng)過的任何地方都可以緩存爆雹,包括代理服務(wù)器停蕉,客戶端等,這樣下次請求將不會到達(dá)服務(wù)端而直接返回response钙态;private則表示只有返回的瀏覽器才可以進(jìn)行緩存慧起;no-cache則表示不可直接用緩存,而是先要到服務(wù)器端進(jìn)行驗證册倒。
第二蚓挤,到期:max-age=<seconds>,代表緩存的時間(秒)驻子;s-maxage=<seconds>,專門為代理服務(wù)器設(shè)置灿意,如果與max-age同時返回,則瀏覽器會讀取max-age拴孤,而代理服務(wù)器則會讀取s-maxage這個設(shè)置脾歧;max-stale=<seconds>,代表在max-age過期后演熟,如果存在max-stale鞭执,而且其時間沒有過期司顿,則表示仍然可以用緩存,max-stale只在request發(fā)起端設(shè)置是有用的兄纺,又因為瀏覽器不會幫助我們帶上這個頭大溜,所以客戶端是瀏覽器的時候這個max-stale是用不到的。
第三估脆,重新驗證:must-revalidate和proxy-revalidate钦奋,這兩個表示緩存過期時間到達(dá)以后,必須要到服務(wù)端重新請求和重新驗證疙赠,這兩個屬性在瀏覽器也不怎么出現(xiàn)付材。
第四,其他圃阳,no-store厌衔,表示本地和代理服務(wù)器都不可以用緩存,必須去重新獲群丛馈富寿;no-transform,告訴代理服務(wù)器不要對返回的body進(jìn)行處理锣夹,比如壓縮等(代理服務(wù)器比如nginx等可以不遵守页徐,但是這個是規(guī)范,最好遵守)银萍。
下面附上做的幾個簡單的例子來加深對上面的理解变勇。例子中通過查看對文件script.js的緩存情況說明問題。
執(zhí)行node server.js砖顷,觀察瀏覽器network如下圖(這里注意贰锁,瀏覽器的Disable cache沒有勾選赃梧,否則會默認(rèn)忽略Cache-Control的設(shè)置):
立刻重新刷新瀏覽器滤蝠,則network中出現(xiàn)下圖:
此時我們可以看見這事size一欄是from memory cache,因為我們設(shè)置max-age為20s授嘀,在這個期間即使我改變script.js的內(nèi)容物咳,瀏覽器仍然會用memory里面的內(nèi)容,而得不到更新蹄皱。很顯然實際開發(fā)中览闰,如果出現(xiàn)這樣的問題,是很可怕的巷折。同時如果每次去后端請求response压鉴,又會使網(wǎng)頁很慢,實際中max-age往往要設(shè)置很大锻拘,表示在本地保存很久的時間油吭,那么下次請求的Time為0击蹲。那么實際開發(fā)中,如何去解決這兩者的矛盾呢婉宰?就是通過改變url的方法歌豺,在請求的文件名后面加上根據(jù)內(nèi)容生成的哈希值(刷新瀏覽器緩存的方案),這樣實際請求的url將會改變心包,那么自然就會去重新請求类咧,如果后端的文件沒有更新,也就是url沒有變蟹腾,則自然會在緩存中讀取痕惋,則不需要經(jīng)過網(wǎng)絡(luò)傳輸,則速度是很快的娃殖,用戶體驗是很好的血巍。network一欄中,這里Size的兩個值珊随,上面表示傳輸時候的大小述寡,下面表示實際的大小(上面的可進(jìn)行壓縮Gzip傳輸叶洞,但是不曉得header可不可以壓縮鲫凶,貌似http2中支持頭壓縮),傳輸時的大小比實際的大衩辟,因為加上了頭信息螟炫。Time的兩個值,上面一行表示從請求開始到接受完最后一個byte為止的時間艺晴。下面一行是Latency昼钻,代表從請求接受完到讀取該資源第一個byte之間的等待時間。
上圖是查找緩存的過程封寞。
如果Cache-Control中max-age的值設(shè)置很大然评,那么一直用本地的緩存肯定是不可取的。所以除了給文件名后面加上哈希碼之外的方法狈究,我們可以通過每次去后端詢問是否文件有所改動碗淌?那么如何來實現(xiàn)這個過程呢?首先在Cache-Control中設(shè)置no-cache抖锥,同時遵從實際情況我們把max-age設(shè)置很大亿眠。更改servr.js如下:
打開network,多次刷新仍然如下:
說明此時已經(jīng)不在緩存中讀取了磅废,即使我們的max-age設(shè)置很大纳像,這是因為我們設(shè)置了no-cache。所以每次我們都不會直接使用緩存了拯勉。那么如何發(fā)揮no-cache的作用呢竟趾,還需要配合資源驗證耙考,資源驗證在http中主要有兩個頭:Last-Modified和Etag。這個內(nèi)容介紹在-資源驗證Last-Modified和Etag中介紹潭兽。