瀏覽器緩存機制淺析(三)

瀏覽器緩存

瀏覽器緩存的知識是前端工程師必須要掌握的,因爲這些知識直接影響到你的頁面的用戶體驗,影響到你的頁面的加載策略。接下來將要詳細的講述瀏覽器緩存的概 念和原理,新人要仔細閱讀,甚至要多次反芻,緩存的知識除了和瀏覽器有關,還涉及到HTTP協議,所以這也是比較難於掌握的內容。

一般在硬件中,緩存在硬件中分一級緩存,二級緩存。但在軟件中的緩存卻不一樣。

狹義上講緩存就叫高速緩存,嚴格講就是將數據暫時存放到某個地方。先要聲明下,我的定義可能不嚴格,但這是我的理解,通俗易懂。

至於存到什麼地方就有很多方式,可放到文件,內存中(如session),還有cache(高速緩存),還有 cookie,session,viewstate,這些是我們經常用到的,但可以認爲他們是緩存數據。其實cache跟session有相似功能,但 cache可在代碼中設置過期時間,依賴項。所謂依賴項(例如:微軟的類cachedependcy sqlCacheDependency)當依賴項變動了,系統會通知cache過期,無效。以上只是說緩存,緩存可是有服務器緩存,客戶端緩存啊。

近些天研究了下客戶端緩存(即瀏覽器緩存),我想跟大家分享,有什麼不同意見可評論。

估計大多數人很少說客戶端緩存,包括我在內。那是因爲我們編程時基本不考慮客戶端緩存,書上也寫得少。其實瀏覽器自動會管理緩存,但瞭解它至少知道有這麼回事,有事編程還要控制客戶端緩存。

瀏覽器緩存就是當你打開一個網頁,瀏覽器會自動下載副本到你電腦上,就相當於你另存爲網頁到某個地方而已,只不過這裏是自動而已。當然不是瀏覽器能把各種 網頁都能下載到本地電腦上,它是有特殊情況。一般html,後者request是get請求,而post一般不緩存。(這個後面會說到)

當然客戶端緩存是否需要是可以在服務端代碼上控制的。那就是響應頭。

響應頭告訴緩存器不要保留緩存,緩存器就不會緩存相應內容;

如果請求信息是需要認證或者安全加密的,相應內容也不會被緩存;

校驗參數非常重要,如果迴應中1個參數都不存在,並且沒有任何信息說明保鮮期(Expires或Cache-Control)的情況下,緩存將不會存儲任何副本; 最常見的校驗參數是文檔的最後修改時間,通過最後Last-Modified頭信息可以,當一份緩存包含Last-Modified信息,他基於此信息,通過添加一個If-Modified-Since請求參數,向服務器查詢:這個副本從上次查看後是否被修改了。 HTTP 1.1介紹了另外一個校驗參數: ETag,服務器是服務器生成的唯一標識符ETag,每次副本的標籤都會變化。由於服務器控制了ETag如何生成,緩存服務器可以通過If-None-Match請求的返回沒變則當前副本和原件完全一致。 所有的緩存服務器都使用Last-Modified時間來確定副本是否夠新,而ETag校驗正變得越來越流行。

響應頭如果是POST模式遞交數據,則返回的頁面大部分不會被瀏覽器緩存,如果你發送內容通過URL和查詢(通過GET模式),則返回的內容可以緩存下來供以後使用。

HTTP協議中關於緩存的信息頭關鍵字包括Cache-Control(HTTP1.1),Pragma(HTTP1.0),last-Modified,Expires等。

緩存控制頭 Cache-Control

Cache-Control 是最重要的規則。這個字段用於指定所有緩存機制在整個請求/響應鏈中必須服從的指令。這些指令指定用於阻止緩存對請求或響應造成不利干擾的行爲。這些指令 通常覆蓋默認緩存算法。緩存指令是單向的,即請求中存在一個指令並不意味着響應中將存在同一個指令。

cache-control 定義是:Cache-Control = “Cache-Control” “:” cache-directive。表 1 展示了適用的值。

表 1. 常用 cache-directive 值

Cache-directive 說明
public 所有內容都將被緩存
private 內容只緩存到私有緩存中
no-cache 所有內容都不會被緩存
no-store 所有內容都不會被緩存到緩存或 Internet 臨時文件中
must-revalidation/proxy-revalidation 如果緩存的內容失效,請求必鬚髮送到服務器/代理以進行重新驗證
max-age=xxx (xxx is numeric) 緩存的內容將在 xxx 秒後失效, 這個選項只在HTTP 1.1可用, 並如果和Last-Modified一起使用時, 優先級較高

表 2 表明在不同的情形下,瀏覽器是將請求重新發送到服務器還是使用緩存的內容。

表 2. 對 cache-directive 值的瀏覽器響應

Cache-directive 打開一個新的瀏覽器窗口 在原窗口中單擊 Enter 按鈕 刷新 單擊 Back 按鈕
public 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器 瀏覽器呈現來自緩存的頁面
private 瀏覽器重新發送請求到服務器 第一次,瀏覽器重新發送請求到服務器;此後,瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器 瀏覽器呈現來自緩存的頁面
no-cache/no-store 瀏覽器重新發送請求到服務器 瀏覽器重新發送請求到服務器 瀏覽器重新發送請求到服務器 瀏覽器重新發送請求到服務器
must-revalidation/proxy-revalidation 瀏覽器重新發送請求到服務器 第一次,瀏覽器重新發送請求到服務器;此後,瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器 瀏覽器呈現來自緩存的頁面
max-age=xxx (xxx is numeric) 在 xxx 秒後,瀏覽器重新發送請求到服務器 在 xxx 秒後,瀏覽器重新發送請求到服務器 瀏覽器重新發送請求到服務器 在 xxx 秒後,瀏覽器重新發送請求到服務器

Cache-Control是關於瀏覽器緩存的最重要的設置,因爲它覆蓋其他設置,比如 Expires 和 Last-Modified。另外,由於瀏覽器的行爲基本相同,這個屬性是處理跨瀏覽器緩存問題的最有效的方法。

過期頭 (Expires)

Expires 頭部字段提供一個日期和時間,響應在該日期和時間後被認爲失效。失效的緩存條目通常不會被緩存(無論是代理緩存還是用戶代理緩存)返回,除非首先通過原始 服務器(或者擁有該實體的最新副本的中介緩存)驗證。(注意:cache-control max-age 和 s-maxage 將覆蓋 Expires 頭部。)

Expires 字段接收以下格式的值:“Expires: Sun, 08 Nov 2009 03:37:26 GMT”。如果查看內容時的日期在給定的日期之前,則認爲該內容沒有失效並從緩存中提取出來。反之,則認爲該內容失效,緩存將採取一些措施。表 3-6 表明針對不同用戶操作的不同瀏覽器的行爲。

表 3. 當用戶打開一個新的瀏覽器窗口時的失效操作

  Firefox 3.5 IE 8 Chrome 3 Safari 4
內容沒有失效 瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面
內容失效 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200

表 4. 當用戶在原始瀏覽器窗口中單擊 Enter 按鈕時的失效操作

  Firefox 3.5 IE 8 Chrome 3 Safari 4
內容沒有失效 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 304
內容失效 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200

表 5. 當用戶按 F5 鍵刷新頁面時的失效操作

  Firefox 3.5 IE 8 Chrome 3 Safari 4
內容沒有失效 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 304
內容失效 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200

表 6. 當用戶單擊 Back 或 Forward 按鈕時的失效操作

  Firefox 3.5 IE 8 Chrome 3 Safari 4
內容沒有失效 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面
內容失效 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器。返回代碼是 200

注意:所有瀏覽器都假定爲使用默認設置運行。

控制文件是否有修改 Last-Modified/E-Tag

Last-Modified 實體頭部字段值通常用作一個緩存驗證器。簡單來說,如果實體值在 Last-Modified 值之後沒有被更改,則認爲該緩存條目有效。ETag 響應頭部字段值是一個實體標記,它提供一個 “不透明” 的緩存驗證器。這可能在以下幾種情況下提供更可靠的驗證:不方便存儲修改日期;HTTP 日期值的 one-second 解決方案不夠用;或者原始服務器希望避免由於使用修改日期而導致的某些衝突。

不同的瀏覽器有不同的配置行爲。表 7-10 表明針對不同用戶操作的不同瀏覽器的行爲。

表 7. 當用戶打開一個新的瀏覽器窗口時的 Last-Modified E-Tag 操作

  Firefox 3.5 IE 8 Chrome 3 Safari 4
內容自上次訪問以來沒有被修改 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 304
內容自上次訪問以來已經被修改 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200

表 8. 當用戶在原始瀏覽器窗口中單擊 Enter 按鈕時的 Last-Modified E-Tag 操作

  Firefox 3.5 IE 8 Chrome 3 Safari 4
內容自上次訪問以來沒有被修改 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 304
內容自上次訪問以來已經被修改 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200

表 9. 當用戶按 F5 鍵刷新頁面時的 Last-Modified E-Tag 操作

  Firefox 3.5 IE 8 Chrome 3 Safari 4
內容自上次訪問以來沒有被修改 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 304 瀏覽器重新發送請求到服務器。返回代碼是 304
內容自上次訪問以來已經被修改 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200

表 10. 沒有緩存設置且用戶單擊 Back 或 Forward 按鈕

  Firefox 3.5 IE 8 Chrome 3 Safari 4
內容自上次訪問以來沒有被修改 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面
內容自上次訪問以來已經被修改 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器呈現來自緩存的頁面 瀏覽器重新發送請求到服務器。返回代碼是 200

注意:所有瀏覽器都假定使用默認設置運行。

不進行任何緩存相關設置

如果您不定義任何緩存相關設置,則不同的瀏覽器有不同的行爲。有時,同一個瀏覽器在相同的情形下每次運行時的行爲都是不同的。情況可能很複雜。另外,有些不該緩存的內容如果被緩存,將會導致安全問題。 不同的瀏覽器有不同的行爲。表 11 展示了不同的瀏覽器行爲。

表 11. 沒有緩存設置且用戶打開一個新的瀏覽器窗口

  Firefox 3.5 IE 8 Chrome 3 Safari 4
打開一個新頁面 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200
在原始窗口中單擊 Enter 按鈕 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器呈現來自緩存的頁面。 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200
按 F5 鍵刷新 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200
單擊 Back 或 Forward 按鈕 瀏覽器呈現來自緩存的頁面。 瀏覽器呈現來自緩存的頁面。 瀏覽器重新發送請求到服務器。返回代碼是 200 瀏覽器重新發送請求到服務器。返回代碼是 200

注意:所有瀏覽器都假定使用默認設置運行。

關鍵結論

最後, 概括下關鍵的結論

操作 行爲
打開新窗口 如果指定cache- control的值爲private、no-cache、must-revalidate,那麼打開新窗口訪問時都會重新訪問服務器。而如果指定了 max-age值,那麼在此值內的時間裏就不會重新訪問服務器,例如:Cache-control: max-age=5 表示當訪問此網頁後的5秒內再次訪問不會去服務器.
在地址欄回車 如果值爲private或must-revalidate,則只有第一次訪問時會訪問服務器,以後就不再訪問。如果值爲no-cache,那麼每次都會訪問。如果值爲max-age,則在過期之前不會重複訪問。
按後退按扭 如果值爲private、must-revalidate、max-age,則不會重訪問,而如果爲no-cache,則每次都重複訪問.
按刷新按扭 無論爲何值,都會重複訪問.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章