atitit。瀏覽器緩存機制 and 微信瀏覽器防止緩存的設計 attilax 總結html
1.6. Etag 主要爲了解決 Last-Modified 沒法解決的一些問題。 4spa
假設已通過期了,那就去server請求,等待server響應,這是很是費時間的,server假設發現資源沒有改變過,那麼就會返回304,告訴瀏覽器。我沒變過,你去讀緩存吧。因而瀏覽器也不用從server拉數據了。然而,等待server響應也是一個很是要命的問題。在網速發達的今天,等一個響應,有時比下載還慢。
304是HTTP狀態碼。server用來標識這個文件沒改動,不返回內容,瀏覽器在接收到個狀態碼後,會使用瀏覽器已緩存的文件
固然瀏覽器在推斷到緩存過時後。請求中頭部附帶If-Modified-Since字段去拉取某一個文件,server會依據這個指定的時間去推斷,假設這個時間點以後沒有改動。也會返回304
做者:: 老哇的爪子 Attilax 艾龍。 EMAIL:1466519819@qq.com
轉載請註明來源: http://blog.csdn.net/attilax
假設是用瀏覽器刷新的,那麼瀏覽器不會去推斷max-age了,直接去server拿,假設server推斷資源沒變過。則仍是會返回304,和
讀取過的文件在http header設置了expire(http 1.0) / max-age(http 1.1),在正常瀏覽時。如未超時,並且瀏覽器也有緩存時。會直接從瀏覽器緩存取出,但假設你在當前頁面按刷新button(F5)時,有的瀏覽器會再次向server發出請求,有些瀏覽器不會。
Expires 頭部字段提供一個日期和時間。在該日期前的所有對該資源的請求都會直接使用瀏覽器緩存而不用向server請求(注意:cache-control max-age 和 s-maxage 將覆蓋 Expires 頭部。
)
Expires 字段接收下面格式的值:「Expires: Sun, 08 Nov 2009 03:37:26 GMT」。
但是使用Expires存在server端時間和瀏覽器時間不一致的問題。
Cache-Control 是最重要的規則。
這個字段用於指定所有緩存機制在整個請求/響應鏈中必須服從的指令。該字段一般覆蓋默認緩存算法。另外,緩存指令是單向的,即請求中存在一個指令並不意味着響應中將存在同一個指令。
簡單地說,該字段用於控制瀏覽器在什麼狀況下直接使用本地緩存而不向server發送請求。
通常具備下面值:
· public: 所有內容都將被緩存
· private: 內容僅僅緩存到似有緩存中
· no-cache: 所有內容都不會被緩存
· no-store: 所有內容都不會被緩存到緩存或者internet暫時文件裏
· must-revalidation/proxy-revalidation: 假設緩存的內容失效。請求必須發送到server/代理以進行又一次驗證
· max-age=xxx( xxx is numeric ): 緩存的內容將在 xxx 秒後失效, 這個選項僅僅在HTTP 1.1可用, 並假設和Last-Modified一塊兒使用時, 優先級較高
當中最常用的屬性即是 max-age, 這個字段很是easy,就是瀏覽器在資源成功請求後的制定時間內,都將直接調用本地緩存和不會向server去請求數據。
Last-Modified和E-tag的做用都是向server確認當前緩存文件是否爲最新。
拋開功能不看。這兩個字段的表現例如如下:
· 若server在響應一個資源時加入了Last-Modified字段,那麼當下一次瀏覽器再一次向server請求該資源時(前提是瀏覽器中上一次的資源被緩存過了),會在請求header中包括If-Modified-Since字段,且值與server第一次響應給瀏覽器的Last-Modified字段一致
· 若server在響應一個資源時加入了ETag字段,那麼當下一次瀏覽器再一次向server請求該資源時(前提是瀏覽器中上一次的資源被緩存過了),會在請求header中包括If-None-Match字段。且值與server第一次響應給瀏覽器的ETag字段一致
那麼上述是遵循了Http協議的瀏覽器會本身主動實現的,而要實現304的功能,就需要server(比方Apache對於靜態資源會本身主動實現這兩個字段的響應)或者咱們手動在server端編寫響應的邏輯來實現。
· 若server在收到的資源請求中發現含有Last-Modified字段。則說明瀏覽器中包括了該資源的某一版本號的緩存。此時server端將依據該字段的值進行必定的邏輯推斷。以決定讓瀏覽器直接使用已有的緩存(返回304)仍是將最新的文件發送過去(200,發送新文件並更新Last-Modified字段)
· 若server在收到的資源請求中發現含有If-None-Matc字段,則說明瀏覽器中包括了該資源的某一版本號的緩存,此時server端將依據該字段的值進行必定的邏輯推斷,以決定讓瀏覽器直接使用已有的緩存(返回304)仍是將最新的文件發送過去(200。發送新文件,並更新ETag)
若同一時候使用了Last-Modified和ETag。正確的作法應該是當二者都符合條件時,才返回304
· 一些文件或許會週期性的更改,但是他的內容並不改變(只改變的改動時間),這個時候咱們並不但願client以爲這個文件被改動了,而又一次GET。
這樣的狀況下可以將某個能用來代表文件內容是否被更改的值(比方md5)來做爲ETag
· 某些文件改動很頻繁,比方在秒下面的時間內進行改動,(比方說1s內改動了N次)。If-Modified-Since能檢查到的粒度是s級的,這樣的改動沒法推斷(或者說UNIX記錄MTIME僅僅能精確到秒)
· 某些server不能精確的獲得文件的最後改動時間
通常咱們打開(或者更新)一個頁面(或者資源)有幾種方式:
· 在地址欄中輸入地址。而後回車
· 激活當前頁面地址,而後回車
· F5刷新頁面
· 單機Back/Forwardbutton
上面幾種方式對資源的請求,會產生不一樣的結果,並且各瀏覽器的表現並不一致。詳細的差異可以參考鳥哥的《瀏覽器緩存機制》
當中你們需要注意的一點是,刷新頁面(F5或者刷新button)。不管是否設置了max-age,都會又一次像server發送請求。
但是這不影響304邏輯。
最後, 歸納下關鍵的結論:
關鍵結論 |
|
打開新窗體 |
假設指定cache-control的值爲private、no-cache、must-revalidate,那麼打開新窗體訪問時都會又一次訪問server。而假設指定了max-age值,那麼在此值內的時間裏就不會又一次訪問server,好比:Cache-control: max-age=5 表示當訪問此網頁後的5秒內再次訪問不會去server. |
在地址欄回車 |
假設值爲private或must-revalidate,則僅僅有第一次訪問時會訪問server,之後就再也不訪問。 假設值爲no-cache,那麼每次都會訪問。假設值爲max-age,則在過時以前不會反覆訪問。 |
按後退按扭 |
假設值爲private、must-revalidate、max-age,則不會重訪問,而假設爲no-cache,則每次都反覆訪問. |
按刷新按扭 |
無論爲什麼值,都會反覆訪問. |
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="0">
這個好像對wechat不起做用。
JSP:
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
覆蓋getLastModified方法,響應消息中無LastModified頭字段
window.location="a-intro.html?"+Math.random();
這個對wechat起做用。。
rdm。html
<script>
window.location="a-intro.html?"+Math.random();
</script>
(3 條消息) 瀏覽器文件緩存和304的差異? - 知乎.htm
[轉載](轉)瀏覽器緩存和304小結_hugh_新浪博客.htm
(very detail good)瀏覽器緩存機制 風雪之隅.htm