引言
前面翻到了http緩存相關內容,關於強制緩存和協商緩存,他們之間的差別可能大家比較清楚。
並且常規情況下是否該使用緩存以及使用哪種緩存,
相關文章多且全,這里不再贅述。
不過用戶的不同行為會打破原有規范,
本文就會去探究下不同行為下的瀏覽器緩存表現。也就是f5到底刷新了哪些內容
瀏覽器緩存
說道瀏覽器緩存,腦海中常見的應該是那么幾種關鍵詞:
Cache-Control、Expires、ETag、If-Match、If-None-Match、Last-Modified等。
根據不同標識的作用,再次訪問某個資源時,
需要緩存的情況下,主要有下面兩種緩存方式
強緩存
一旦資源命中強緩存, 瀏覽器便不會向服務器發送請求, 而是直接讀取緩存.
Chrome下的現象是 200 OK (from disk cache) 或者 200 OK (from memory cache).
協商緩存
也就是我們常見的304狀態碼。
緩存過期后, 繼續請求該資源,
對於現代瀏覽器, 存在如下兩種做法:
- 根據上次響應中的ETag_value, 自動往request header中添加If-None-Match字段.
服務器收到請求后, 拿If-None-Match字段的值與資源的ETag值進行比較,
若相同, 則命中協商緩存, 返回304響應. - 根據上次響應中的Last-Modified_value, 自動往request header中添加If-Modified-Since字段. 服務器收到請求后, 拿If-Modified-Since字段的值與資源的Last-Modified值進行比較, 若相同, 則命中協商緩存, 返回304響應.
ETag是http/1.1新增標識,也是為了解決Last-Modified存在的一些問題。
例如服務器和客戶端時間不同步等問題,
所以比Last-Modified的優先級高。
因此常見情況下,資源的緩存就是按照上面的順序,強緩存=>協商緩存=>重新獲取。
但是,緩存策略是與用戶的操作相關的,平時不可避免會用到刷新。
刷新的方式是多種多樣的。刷新按鈕,command+r,shift+command+r等。他們之間的區別是什么呢。以http://xxdy.tech/作為例子來看一下。
再次訪問(地址欄回車)
可以看到資源分下面幾類:
先看下直觀的請求

大部分都是200強緩存,只有文稿是304
- 無緩存的,maxage=0的資源

此類資源,請求的時候總會從服務端重新加載
- status為200,但是后面有提示from memory cache 或者disk cache的標識。 這種緩存的字體為灰色,跟上面的200還是比較容易看出來差別的。
css資源的響應,來自硬盤緩存。
js的響應,即來自memory的緩存

這里就是強緩存,直接從本地緩存中讀取。
因為Cache-Control:max-age=600 刷新時未過期,所以會從本地緩存中獲取。

這里截兩張圖的原因在於兩者緩存存放的位置是不同。
概述一下(詳細請找資料細究)
-
內存緩存(from memory cache):內存緩存具有兩個特點,分別是快速讀取和時效性
快速讀取:內存緩存會將編譯解析后的文件,直接存入該進程的內存中,占據該進程一定的內存資源,以方便下次運行使用時的快速讀取
時效性:一旦該進程關閉,則該進程的內存則會清空。 -
硬盤緩存(from disk cache):硬盤緩存則是直接將緩存寫入硬盤文件中,讀取緩存需要對該緩存存放的硬盤文件進行I/O操作,然后重新解析該緩存內容,讀取復雜,速度比內存緩存慢。
在瀏覽器中,大部分情況下瀏覽器會在js和圖片等文件解析執行后直接存入內存緩存中,
那么當刷新頁面時只需直接從內存緩存中讀取(from memory cache);
而css文件則會存入硬盤文件中,所以每次渲染頁面都需要從硬盤讀取緩存(from disk cache)
- 協商緩存
status為304,意為與服務端對比之后文件未改變,返回原有緩存資源。

此資源請求頭里面有Cache-Control: max-age=0 ,
所以每次請求都回去服務端詢問,不會走強緩存,因為服務端也未更新,etag相同,所以返回緩存資源。
總結
地址欄回車的話,就是我們正常訪問,遵循瀏覽器的緩存策略。
f5刷新(mac 即command + r)
f5刷新的時候,會有什么不同嗎,先直觀對比下。

好像沒什么不同,具體到文件也是與直接回車相同的狀態。
總結
那么f5的刷新到底是什么呢,
可以看到f5可以被稱為soft refresh 其只是reload page而已。
即與回車地址相同,正常規則下的緩存還是會涉及到。
強制刷新(command+shift+r)
此時可以看下請求結果,前面列出的304和from cache的項目都是重新load。

具體查看相應請求可以看到,
在request中多了個屬性:
都有Cache-Control: no-cache的標識。
這表明每次都需要服務器評估是否有效,不要理解為直接不使用緩存。
此外可以注意到request中沒有可以匹配response中ETag的If-None-Match屬性,
所以會重新加載。
總結而言
此時的刷新可以稱為hard refresh,
請求會加上一個Cache-Control:no-cache的標識來表明突破cache-control的限制,
需要服務端重新判斷有效性,即不走強緩存。
另外請求header中去掉If-None-Match,這樣就不能使用協商緩存。拉到新的資源
tip
這里硬性重新加載,有些文件是依舊使用緩存的,我這邊看到是有些小的image,沒有找到合理的解釋。具體我需要在研究一下,后面補上

停用緩存並刷新
針對上面提到的哪些文件,此時就需要到下面這種清空緩存並硬性重新加載了。

操作完之后就完全不使用緩存了。
規則
上面提到那么幾種刷新方式對應的效果,可能不同瀏覽器的實現也不同。找了個相對完善的大家可以參考一下。

結束語
到這里,關於刷新與緩存的個人一些關掉就結束了,拋磚引玉,希望能對有需要的人有所幫助,也希望有大神有所指教。更多個人博客請移步
此外感謝下面的參考文章:
https://stackoverflow.com/questions/8589760/difference-between-f5-ctrl-f5-and-click-or-refresh-button
https://stackoverflow.com/questions/385367/what-requests-do-browsers-f5-and-ctrl-f5-refreshes-generate
