伺服器網頁緩衝的深入分析

來源:互聯網
上載者:User

Expires、Cache-Control、Last-Modified、ETag是RFC
2616(HTTP/1.1)協議中和網頁緩衝相關的幾個欄位。前兩個用來控制緩衝的失效日期,後兩個用來驗證網頁的有效性。要注意的是,
HTTP/1.0有一個功能比較弱的緩衝控制機制:Pragma,使用HTTP/1.0的緩衝將忽略Expires和Cache-Control頭。我們
這裡以Apache2.0伺服器為例,只討論HTTP/1.1協議。

Expires

Expires欄位聲明了一個網頁或URL地址不再被瀏覽器緩衝的時間,一旦超過了這個時間,瀏覽器都應該聯絡原始伺服器。RFC告訴我們:“由於推斷的失效時間也許會降低語義透明度,應該被謹慎使用,同時我們鼓勵原始伺服器儘可能提供確切的失效時間。”

對於一般的純靜態頁面,如html、gif、jpg、css、js,預設安裝的Apache伺服器,不會在回應標頭添加這個欄位。Firefox瀏覽器接受
到相應後,如果發現沒有Expires欄位,瀏覽器根據檔案的類型和“Last-Modified”欄位來推斷出一個合適的失效時間,並儲存在用戶端。推
測出的時間一般是接受到回應時間後的三天左右。

Apache的expires_module模組可以在Http回應標頭部自動加上Expires欄位。在Apache的httpd.conf檔案中進行如下配置:

#啟用expires_module模組
LoadModule expires_module modules/mod_expires.so
# 啟用有效期間控制
ExpiresActive On
# GIF有效期間為1個月
ExpiresByType image/gif A2592000
# HTML文檔的有效期間是最後修改時刻後的一星期
ExpiresByType text/html M604800
#以下的含義類似
ExpiresByType text/css “now plus 2 month”
ExpiresByType text/js “now plus 2 day”
ExpiresByType image/jpeg “access plus 2 month”
ExpiresByType image/bmp “access plus 2 month”
ExpiresByType image/x-icon “access plus 2 month”
ExpiresByType image/png “access plus 2 month”

對於動態網頁面,如果在頁面內部沒有通過函數強制加上Expires,例如header(”Expires: ” . gmdate(”D, d M Y
H:i:s”) . ” GMT”),Apache伺服器會把Wed, 11 Jan 1984 05:00:00 GMT
作為Expires欄位內容,返回給瀏覽器。即認為動態網頁面總是失效的。而瀏覽器仍然會儲存已經失效的動態網頁面。

可以發現Firefox瀏覽器總是緩衝所有頁面,不管失效、不失效還是沒有聲明失效時間。即使緩衝中聲明了一個網頁的失效日期是1970-01- 01
08:00:00,瀏覽器仍然會發送該檔案在緩衝中的Last-Modified和ETag欄位。如果在伺服器端驗證通過,返回304狀態,瀏覽器就還會
使用此緩衝。

Cache-Control

Cache-Control欄位中可以聲明多些元素,例如no-cache, must-revalidate,
max-age=0等。這些元素用來指明頁面被緩衝最大時限,如何被緩衝的,如何被轉換到另一個不同的媒介,以及如何被存放在持久媒介中的。但是任何一個
Cache-Control指令都不能保證隱私性或者資料的安全性。“private”和“no-store”指令可以為隱私性和安全性方面提供一些幫
助,但是他們並不能用於替代身分識別驗證和加密。

Apache的mod_cern_meta模組允許檔案級Http回應標頭部的控制,同時它也可以配置Cache-Control頭(或任何其他頭)。回應標頭檔案是放在原始目錄的子目錄中,根據原始檔案名所命名的一個檔案。具體用法請參閱Apache的官方網站。

其中Cache-Control :
max-age表示失效日期。如果沒有啟動mod_cern_meta模組,Apache伺服器會把Expires欄位中的日期換算成以秒為單位的一個
delta值,賦值給max-age。如果啟動mod_cern_meta模組,並且配置了max-age值,Apache會將這個覆蓋Expires字
段。同時,max-age隱含了Canche-Control: public。這樣瀏覽器接受到的Cache-Control :
max-age和Expires值就是一致的。

如果失效日期Cache-Control : max-ag=0或者是負值,瀏覽器會在對應的緩衝中把Expires設定為1970-01-01 08:00:00。

Last-Modified

Last-Modified和ETag是條件請求(Conditional
Request)相關的兩個欄位。如果一個緩衝收到了針對一個頁面的請求,它發送一個驗證請求詢問伺服器頁面是否已經更改,在HTTP頭裡面帶上”
ETag”和”If Modify Since”頭。伺服器根據這些資訊判斷是否有更新資訊,如果沒有,就返回HTTP 304(Not
Modify);如果有更新,返回HTTP 200和更新的頁面內容,並且攜帶新的”ETag”和”Last-Modified”。

使用這個機制,能夠避免重複傳送檔案給瀏覽器,不過仍然會產生一個HTTP請求。

一般純靜態頁面本身都會有Last-Modified資訊,Apache伺服器會讀取分頁檔中的Last-Modified資訊,並添加到http回應標頭部。

對於動態網頁面,如果在頁面內部沒有通過函數強制加上Last-Modified,例如header(”Last-Modified: ” .
gmdate(”D, d M Y H:i:s”) . ”
GMT”),Apache伺服器會把目前時間作為Last-Modified,返回給瀏覽器。

無論是純靜態頁面還是動態網頁面,Firefox瀏覽器巧妙地按照接受到伺服器響應的時間設定快取頁面面的Last-Modified,而不是按照http回應標頭部中的Last-Modified欄位。

ETag

既然有了Last-Modified,為什麼還要用ETag欄位呢?因為如果在一秒鐘之內對一個檔案進行兩次更改,Last-Modified就會不正確。因此,HTTP/1.1利用Entity Tag頭提供了更加嚴格的驗證。

Apache伺服器預設情況下,會對所有的靜態、動態檔案的回應標頭添加ETag欄位。

在Apache的httpd.conf檔案中可以通過FileETag指令配置該選項。FileETag指令配置了當文檔是基於一個檔案時用以建立
Etag(entity tag)回應標頭的檔案的屬性。在Apache
1.3.22及以前,ETag的值是對檔案的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後得到的。如果一個目錄的
配置包含了‘FileETag INode MTime Size’而其一個子目錄包含了‘FileETag
-INode’那麼這個子目錄的設定(並會被其下任何沒有進行覆蓋的子目錄繼承)將等價於‘FileETag MTime Size’。

在多台Server Load Balancer的伺服器環境下,同一個檔案會有不同的etag或者檔案修改日期,瀏覽器每次都會重新下載。設定‘FileETag None’可以使回應標頭不再包含ETag欄位。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.