在瀏覽器里中,按F5鍵和按F5同時按住Ctrl鍵(簡稱Ctrl+F5),效果是不同,到底兩者有什么區別呢?
假如我第一次訪問過http://localhost/home,這個網頁是個動態網頁,每次訪問都會去訪問Server,但是它包含一個一個靜態資源http://localhost/content/bootstrap.css,瀏覽器在顯示這個網頁之前需要發HTTP請求獲取這個bootstrap.css文件,返回的HTTP response包含這樣的Headers:

下次我再通過bookmark或者通過在URI輸入欄直接敲字的方法訪問http://localhost/home的時候,瀏覽器一看本地有個bootstrap.css,而且它還沒過期呢,就不會發HTTP request給server,而是直接把本地cache中的bootstrap.css顯示了。
F5的作用和直接在URI輸入欄中輸入然后回車是不一樣的,F5會讓瀏覽器無論如何都發一個HTTP Request給Server,即使先前的Response中有Expires Header。所以,當我在當前http://localhost/home網頁中按F5的時候,瀏覽器會發送一個HTTP Request給Server,但是包含這樣的Headers:
If-Modified-Since: Wed, 20 Jan 2016 10:24:40 GMT
實際上Server沒有修改這個bootstrap.css文件,所以返回一個304 (Not Modified),這樣的Response很小,所以round-trip耗時不多,網頁很快就刷新了。

上面的例子中沒有考慮ETag,如同在上一篇技術文章中所說,最好就不要用ETag,但是如果Response中包含ETag,F5引發的Http Request中也是會包含If-None-Match的。
那么Ctrl+F5呢? Ctrl+F5要的是徹底的從Server拿一份新的資源過來,所以不光要發送HTTP request給Server,而且這個請求里面連If-Modified-Since/If-None-Match都沒有,這樣就逼着Server不能返回304,而是把整個資源原原本本地返回一份。

實際上,為了保證拿到的是從Server上最新的,Ctrl+F5不只是去掉了If-Modified-Since/If-None-Match,還需要添加一些HTTP Headers。按照HTTP/1.1協議,Cache不光只是存在Browser終端,從Browser到Server之間的中間節點(比如Proxy)也可能扮演Cache的作用,為了防止獲得的只是這些中間節點的Cache,需要告訴他們,別用自己的Cache敷衍我,往Upstream的節點要一個最新的copy吧。
在IE6中,Ctrl+F5會添加一個Header
Pragma: no-cache
在Firefox 2.0中,Ctrl+F5會添加兩個
Pragma: no-cache
Cache-Control: max-age=0
作用就是讓中間的Cache對這個請求失效,這樣返回的絕對是新鮮的資源

Pragma 當"no-cache"出現在請求消息中時,應用程序應當向原始服務器推送此請求,即使它已
經在上次請求時已經緩存了一份拷貝。這樣將保證客戶端能接收到最權威的回應。它也用來
在客戶端發現其緩存中拷貝不可用或過期時,對拷貝進行強制刷新。
cache-control
max-age>0 時 直接從游覽器緩存中 提取
max-age<=0 時 向server 發送http 請求確認 ,該資源是否有修改
有的話 返回200 ,無的話 返回304.
