Expires、Last-Modified、Etag緩存控制


當請求一個頁面時,如果瀏覽器使用本地緩存,因此我們經常會看到一個HTTP請求為304狀態。或者顯示200狀態,在chrome下標注是from cache,在火狐下會標注BFCache;

我們希望在服務器端更新了靜態文件(如css、js、圖片),能夠在客戶端得到及時的更新,但又不想讓瀏覽器每次請求都從服務器端獲取靜態資源。那么就需要了解一些下面的知識:

Last-Modified / If-Modified-Since

當瀏覽器第一次請求一個url時,服務器端的返回狀態碼為200,同時HTTP響應頭會有一個Last-Modified標記着文件在服務器端最后被修改的時間。

瀏覽器第二次請求上次請求過的url時,瀏覽器會在HTTP請求頭添加一個If-Modified-Since的標記,用來詢問服務器該時間之后文件是否被修改過。

如果服務器端的資源沒有變化,則自動返回304狀態,使用瀏覽器緩存,從而保證了瀏覽器不會重復從服務器端獲取資源,也保證了服務器有變化是,客戶端能夠及時得到最新的資源。

Etag / If-None-Match

當瀏覽器第一次請求一個url時,服務器端的返回狀態碼為200,同時HTTP響應頭會有一個Etag,存放着服務器端生成的一個序列值。

瀏覽器第二次請求上次請求過的url時,瀏覽器會在HTTP請求頭添加一個If-None-Match的標記,用來詢問服務器該文件有沒有被修改。

 

 

Etag 主要為了解決 Last-Modified 無法解決的一些問題:

1、一些文件也許會周期性的更改,但是他的內容並不改變(僅僅改變的修改時間),這個時候我們並不希望客戶端認為這個文件被修改了,而重新GET;
2、某些文件修改非常頻繁,比如在秒以下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改無法判斷(或者說UNIX記錄MTIME只能精確到秒)
3、某些服務器不能精確的得到文件的最后修改時間;
 

Expires

<meta http-equiv="expires" content="Fri, 22 Aug 2014 00:52:49 GMT" />

HTTP 1.0,設置緩存的截止時間,在此之前,瀏覽器對緩存的數據不重新發請求。它與Last-Modified/Etag結合使用,用來控制請求文件的有效時間,當請求數據在有效期內,瀏覽器從緩存獲得數據。Last-Modifed/Etag能夠節省一點寬帶,但是還會發一個HTTP請求。

Catch-Control

<!--Cache-Control: max-age=秒 -->
<meta http-equiv="Cache-Control" content="max-age=120"/>

HTTP 1.1,設置資源在本地緩存多長時間。

如果Cache-Control與expires同時存在,Cache-Control生效。expires 的一個缺點就是,返回的到期時間是服務器端的時間,這樣存在一個問題,如果客戶端的時間與服務器的時間相差很大,那么誤差就很大,所以在HTTP 1.1版開始,使用Cache-Control: max-age=秒替代。

用戶操作與緩存

禁止緩存

<!--禁止瀏覽器本地緩存 -->
<meta http-equiv="Cache-Control" content="no-cache"/>

<!-- 或者 -->
<meta http-equiv="Cache-Control" content="max-age=0"/>

還有POST請求不使用緩存,HTTP響應頭不包含Last-Modified/Etag,也不包含Cache-Control/Expires不會使用緩存。

除非有特殊需求,最好還是不要禁用緩存,畢竟是用緩存能節省寬帶,節省服務器資源,節省money...

瀏覽器第一次請求過程

瀏覽器第二次請求過程

我們希望服務器端更新了文件,客戶端可以及時的更新文件,根具上面流程,我們需要針對靜態文件的響應頭添加expires,設置為永久過期,瀏覽器每次請求靜態文件,就會詢問服務器文件有沒有做過更改,如果更改了就從服務器端獲取資源,否則直接使用緩存。  

apache的配置:

#開啟mod_expires模塊
LoadModule expires_module modules/mod_expires.so

ExpiresActive On
ExpiresDefault "access plus 0 seconds" #默認緩存0s
<Directory  "根目錄">
    #Options FollowSymLinks
    #AllowOverride all
    Order deny,allow
    Allow from all
    #ExpiresByType application/* "access plus 0 seconds"
    #ExpiresByType image/* "access plus 0 seconds"
    #ExpiresByType text/css "access plus 0 seconds"
</Directory>

這樣的做法有個弊端,就是每次請求都會詢問服務器端資源是否過期,當然還有更好的辦法。

不管怎樣,適合自己項目的就是好方法。

 

Apache mode_expires模塊配置:

http://httpd.apache.org/docs/2.0/mod/mod_expires.html

 

針對大型互聯網項目,推薦的靜態資源管理方案:

靜態資源版本更新與緩存

靜態資源管理與模板框架 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM