瀏覽器的緩衝策略,會暫時將瀏覽過的檔案快取在本地磁碟。當使用者重複請求頁面時,告知用戶端頁面並沒有發生改變,可以調用緩衝。 那麼如何知道用戶端是否有頁面緩衝呢?從 HTTP 協議層面來說,瀏覽器發送請求時會先發送如下
HTTP 頭:
Connection Keep-Alive
Date Sun, 06 May 2012 18:00:36 GMT
Last-Modified Sun, 06 May 2012 17:31:02 GMT
Etag ec1f629013925ab0fa4389ba926e8c06
Keep-Alive timeout=15, max=299
Server Apache/2.2.16 (Unix) DAV/2
Vary Accept-Encoding
請注意其中的這兩行,描述了頁面的緩衝資訊:
Last-Modified Sun, 06 May 2012 17:31:02 GMT
Etag ec1f629013925ab0fa4389ba926e8c06這個情況下,如果伺服器響應 304 狀態代碼,瀏覽器會自覺地從緩衝中讀取資料;如果響應 200 狀態代碼,不管有沒有用戶端緩衝,照樣從服務端讀取。
按照這個理論支撐,比如站長軍團大部分查詢結果都是 ajax 非同步擷取的,二次訪問就都可以通過這種方式進行緩衝改造。只要用戶端有緩衝,就向用戶端發送一個 304 響應狀態代碼,然後退出程式執行。
瀏覽器發出的請求中包含 If-Modified-Since 和 If-None-Match 兩個參數:
If-Modified-Since 表示詢問資料的最後修改時間是否是某個時間值。然後伺服器會檢查資料的最後修改時間,如果是該時間則返回 304 狀態代碼,用戶端接收到該狀態代碼後直接從本地讀取緩衝。這種情況有一個前置條件,即本地必須存在緩衝資源,瀏覽器才會發送 If-Modified-Since 參數,並且值為上一次伺服器返回的 Last-Modified 值。
If-None-Match 類似,它由伺服器返回的 Etag 值產生,僅僅用於伺服器檢查資料的修改時間,可以是任意值。考慮到 If-Modified-Since 結合 Last-Modified 的方法並不被所有伺服器支援,這裡就只考慮使用 etag 的實現。
PHP 中通過 $_SERVER['HTTP_IF_NONE_MATCH'] 可以判斷檔案是否被瀏覽器緩衝,程式碼片段如下:
//使用 etag 標記控制緩衝
| 代碼如下 |
複製代碼 |
$etag = md5(date('Ymd')); if ($_SERVER['HTTP_IF_NONE_MATCH'] == $etag) { header('Etag:' . $etag, true, 304); exit(); } else { header('Etag:' . $etag);
|
}這裡我使用當日日期來產生 etag,這樣可以保證緩衝最多生效一天時間,這個參數可以根據需要修改。
補充說明:
即便是 304 響應,實際上還是會請求服務端,因為需要建立串連來判斷是否需要傳輸資料,304 緩衝節約的是靜態資源傳輸的開銷;
另一種緩衝是 200 響應時的緩衝,不建立串連但請求會響應 200 狀態代碼,並從本地直接讀取緩衝。
http://www.bkjia.com/PHPjc/444666.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/444666.htmlTechArticle瀏覽器的緩衝策略,會暫時將瀏覽過的檔案快取在本地磁碟。當使用者重複請求頁面時,告知用戶端頁面並沒有發生改變,可以調用緩衝。 那...