Apache 設定 expire 的方式很簡單:
- a2enmod expires # enable mod_expires
- 編輯 /etc/apache/conf.d/cache.conf (檔名隨便取):
ExpiresActive On ExpiresByType text/css "access plus 4 weeks" ExpiresByType text/js "access plus 4 weeks" ExpiresByType image/gif "access plus 4 weeks" ExpiresByType image/jpeg "access plus 4 weeks" ExpiresByType image/png "access plus 4 weeks"
這樣會把 CSS、JavaScript 和常用圖檔設成使用者拿到檔案的四週後才會過期。
但設了 expire time 後帶出一個新問題, 萬一 server 端在 expire time 前有更新檔案怎麼辦? 在該頁的留言裡有討論幾種解法的優缺點:
- 加版本編號到檔名裡, 如 yahoo_2.0.6.js, Yahoo 是這麼做的。缺點是要改 code (HTML header、CSS 內文等), 也得想想怎麼和版本控制整合, 變成每次 deployment 就得改檔名。
- 加上 query string, 像是 base.css?v=CREATED_TIMESTAMP。缺點是有些 CDN 業者和 Proxy 不支援靜態檔案的 query string, 若它們忽略 query string, 靜態檔案就不會被更新了。也有人提到 HTTP 1.1 規定有 query string 的檔案不能被 cache, 雖說大部份瀏覽器仍會 cache。但也有人提到 HTTP 1.1 規定有送出 expire time 就能被 cache。無論如何, CDN 業者和 Proxy 的問題較頭大。
- 加上 virtual URL, 像是 /media/css/base.css 變成 /media/VERSION/css/base.css, 這樣就無 CDN、Proxy 的問題。不過不知道要怎麼在 web server 做對應的處置較好, 設 alias 忽略中間那段似乎是最簡單的解法? 即設個 alias 將 /media/VERSION/css/base.css 指到 /media/css/base.css。這樣 CSS 內用相對路徑取圖的話, 應該也不用改 CSS code。修改幅度最小。
- Firefox 的 YSlow 會查那些靜態檔案沒設 expire time。
- Firefox 的 Live HTTP Headers 會秀出目前連線的所有 http connection 的 request 和 response headers。可以用來查看 Expire 是否有被設對, 還有 client 是否真的沒發出 request。
- Chrome 的 Speed Tracer 可以秀出頁面載入所有檔案的開始時間, 包含 http request、response 開始和結束的時間。也有 header 內的訊息。多種願望, 一次滿足!!
瀏覽器對待 expire time 的行為如下 (試出來的):
- Firefox 按重新整理就不會理會 expire time, 在網址列按 Enter 重讀會參考 expire time。
- Chrome 按重新整理或在網址列按 Enter 重讀都不會理會 expire time, 只有在網頁內點選的連結才會參考 expire time。
第二步驟少寫了IfModule mod_expires.c開頭以及結尾/IfModule
回覆刪除難怪一開始設不起來...
有執行 a2enmod expires 的話應該OK才對, 加 IfModule 的用意是, 沒 enable 時就忽略那段設定
回覆刪除那可能是YSlow的問題
回覆刪除YSlow一直說我沒有Enable expire time
可是裝了Live HTTP Header明明就有看到一個月後expire...
然後第二次Firefox就不會發request了,除非按下Ctrl+F5
回覆刪除