接續前面那一篇「動態網頁也可以被快取喔!」
前面這樣的修改事實上仍不太夠,在某些狀況下仍無法節省頻寬,甚至有些時候會發生檔案更新後,抓到的檔案還是舊的 🙁
這一篇作法嘗試進一步解決這些問題,我們把前面的程式再作一些修改:
<? # http://bbs.giga.net.tw/demo/dl-test3.php $filename = 'Peacock.jpg'; $ims = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE'] ); $mod_time = gmdate('D, d M Y H:i:s', filemtime($filename)) . ' GMT'; if( $mod_time == $ims ) { header( 'HTTP/1.0 304 Not Modified' ); exit; } header( 'Cache-Control: max-age=60' ); header( 'Last-Modified: ' . $mod_time ); header( 'Content-Type: application/octet-stream' ); header( 'Content-Length: ' . filesize($filename) ); header( 'Content-Transfer-Encoding: binary' ); header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); $fp = fopen( $filename, 'rb' ); while( !feof($fp) ) { echo fread( $fp, 1024 ); } fclose($fp); ?> |
這邊作一些說明:
WebAMP 對於已經存取過的檔案,會對 Web Server 發出 If-Modified-Since 的請求,要求 Web Server 確認該檔案是否已經修改過了
所以程式首先抓取 $_SERVER[‘HTTP_IF_MODIFIED_SINCE’] 變數,與 Last-Modified 比較,如果發現兩者相同,就回傳 HTTP/1.0 304 Not Modified 告知 WebAMP 這個檔案沒更新過然後直接結束程式 ( exit ),避免耗費頻寬
另外就是加上 Cache-Control: max-age=60 這個指令:
max-age 的效用等同以前的 Expires: header,但是使用起來更方便一點 (只須指定秒數)
max-age=60 是告知 WebAMP 該檔案 60 秒內都不會更新
這個設定會讓 WebAMP 在 60 秒內都不會來問 Web Server 是否有更新,可以降低 Server 的一些負載,超過 60 秒以後,WebAMP 會用 If-Modified-Since 的方式去問 Web Server 該檔案是否有更新
你可以依據需求以及檔案更新的頻率來適當調整這個數值
修改之後,除了第一次之外,結果當然是讓人滿意的囉:
# wget -v -S 'http://bbs.giga.net.tw/demo/dl-test3.php' --15:12:36-- http://bbs.giga.net.tw/demo/dl-test3.php => `dl-test3.php' Resolving bbs.giga.net.tw... done. Connecting to bbs.giga.net.tw[203.187.29.180]:80... connected. HTTP request sent, awaiting response... 1 HTTP/1.0 200 OK 2 Date: Mon, 01 Aug 2005 07:04:49 GMT 3 Server: Apache/2.0.54 (FreeBSD) PHP/5.0.4 4 X-Powered-By: PHP/5.0.4 5 Cache-Control: max-age=60 6 Last-Modified: Tue, 18 May 2004 08:53:23 GMT 7 Content-Length: 1474750 8 Content-Transfer-Encoding: binary 9 Content-Disposition: attachment; filename="Peacock.jpg" 10 Content-Type: application/octet-stream 11 X-Cache: HIT from WebAmpRP@GIGAMEDIA 12 Connection: close 100%[====================================>] 1,474,750 1.32M/s
最後,我們回過頭來看看 Web Server 端的 LOG (access.log)
第一次下載 dl-test3.php 時,當然是 MISS 的,這時候的狀態碼是 200 :
203.187.29.181 - - [01/Aug/2005:14:51:01 +0800] "GET /demo/dl-test3.php HTTP/1.0" 200 1474750 "http://bbs.giga.net.tw/" "Wget/1.8.2"
由於我們前面設定了 max-age=60,因此在 60 秒之內重複下載 dl-test3.php,都會由 WebAMP 直接處理掉,而不會在 Web Server 上面看到任何 LOG
但超過 60 秒後,你就會在 Web Server 上面看到 304 的狀態碼 (要求確認是否更新過):
203.187.29.181 - - [01/Aug/2005:14:52:06 +0800] "GET /demo/dl-test3.php HTTP/1.0" 304 - "http://bbs.giga.net.tw/" "Wget/1.8.2"
確認過後,一樣要再隔 60 秒才會再向 Web Server 問一次 If-Modified-Since
最後,想瞭解更進一步資訊的,下面幾個連結可以參考看看:
- Caching Tutorial (for Web Authors and Webmasters)
- HTTP 1.1 – Header Field Definitions
歡迎大家都來試用看看 WebAMP 的服務!
以上這些作法不只適用於 WebAMP,只要您想要讓動態網頁可以被 Proxy 快取,都可以使用上述方法來修改程式
自動引用通知: 動態網頁也可以被快取喔! | Dada's Blog
很受用!