當請求一個頁面時,如果瀏覽器使用本地緩存,因此我們經常會看到一個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 無法解決的一些問題:
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
針對大型互聯網項目,推薦的靜態資源管理方案: