HTTP協議ETag窺探

2021-05-25 02:11:17 字數 2823 閱讀 6133

我們都知道,http/1.1中有乙個etag,用來判斷請求的檔案是否被修改。

為什麼要使用etag呢?etag主要為了解決last-modified無法解決的一些問題

1、一些檔案也許會週期性的更改,但是他的內容並不改變(僅僅改變的修改時間),這個時候我們並不希望客戶端認為這個檔案被修改了,而重新get;

2、某些檔案修改非常頻繁,比如在秒以下的時間內進行修改,(比方說1s內修改了n次),if-modified-since能檢查到的粒度是s級的,這種修改無法判斷(或者說unix記錄mtime只能精確到秒)

3、某些伺服器不能精確的得到檔案的最後修改時間;

為此,http/1.1引入了etag(entity tags).etag僅僅是乙個和檔案相關的標記,可以是乙個版本標記,比如說v1.0.0或者說」2e681a-6-5d044840″這麼一串看起來 很神秘的編碼。但是http/1.1 標準並沒有規定etag的內容是什麼或者說要怎麼實現,唯一規定的是etag需要放在」"內。

etag由伺服器端生成,客戶端通過if-match或者說if-none-match這個條件判斷請求來驗證資源是否修改。我們常見的是使用if-none-match.請求乙個檔案的流程可能如下:

====第一次請求===

1.客戶端發起http get請求乙個檔案;

2.伺服器處理請求,返回檔案內容和一堆header,當然包括etag(例如」2e681a-6-5d044840″)(假設伺服器支援etag生成和已經開啟了etag). 狀態碼200

====第二次請求===

1.客戶端發起http get請求乙個檔案,注意這個時候客戶端同時傳送乙個if-none-match頭,這個頭的內容就是我們第一次請求時伺服器返回的etag:2e681a-6-5d044840

2.伺服器判斷傳送過來的etag和計算出來的etag匹配,因此if-none-match為false,不返回200,返回304,客戶端繼續使用本地快取;

流程很簡單,問題是,如果伺服器又設定了cache-control:max-age和expires呢,怎麼辦?

答案是同時使用,也就是說在完全匹配if-modified-since和if-none-match即檢查完修改時間和etag之後,伺服器才能返回304.(不要陷入到底使用誰的問題怪圈)

我們來看apache中的etag實現。

1.apache首先判斷是不是弱etag,這個留在下面講。如果不是,進入第二種情況:

強etag根據配置檔案中的配置來設定etag值,預設的apache的fileetag設定為:

fileetag inode mtime size

也就是根據這三個屬性來生成etag值,他們之間通過一些演算法來實現,並輸出成hex的格式,相鄰屬性之間用-分隔,比如:

etag 「2e681a-6-5d044840″

這裡面的三個段,分別代表了inode,mtime,size根據演算法算出的值的hex格式,(如果你在這裡看到了非hex裡面的字元(也就是0-f),那你可能看見神了:))

當然,我們可以改變apache的fileetag設定,比如設定成fileetag size,那麼得到的etag可能為:

etag 「6″

總之,設定了幾個段,etag值就有幾個段。(不要誤以為etag就是固定的3段式)

說明

這裡說的都是apache 2.2裡面的etag實現,因為http/1.1並沒有規定etag必須是什麼樣的實現或者格式,因此,你也可以修改或者完全編寫自己的演算法得到 etag,比如 「2e681a65d044840″,客戶端會記住並快取下這個etag(windows裡面儲存在**,我還沒找到:(), 下次訪問的時候直接拿這個值去和伺服器生成的etag對比。

注意

不管怎麼樣的演算法,在伺服器端都要進行計算,計算就有開銷,會帶來效能損失。因此為了榨乾這一點點效能,不少**完全把etag禁用了(比如yahoo!),這其實不符合http/1.1的規定,因為http/1.1總是鼓勵伺服器盡可能的開啟etag。

弱校驗(弱etag)

重新考慮前面提到的3個問題:

問題1、一些檔案也許會週期性的更改,但是他的內容並不改變(僅僅改變的修改時間),這個時候我們並不希望客戶端認為這個檔案被修改了,而重新get;

解決辦法:如果使用強etag,每次得會要求重新get頁面,如果使用etag,比方說設定成fileetag size等,就可以忽略mtime造成的last-modified時間修改從而影響了if-modified-since(ims)這個校驗了。這點和 弱etag無關。

問題2、某些檔案修改非常頻繁,比如在秒以下的時間內進行修改,(比方說1s內修改了n次),if-modified-since能檢查到的粒度是s級的,這種修改無法判斷(或者說unix記錄mtime只能精確到秒)

解決辦法:如果是這種情況,apache會自動判斷請求時間和修改時間之間的差值,如果小於1s,apache 會認為這個檔案在這1秒內可 能會再次被修改,因此生成乙個弱etag(weak etag),這個etag僅僅基於mtime來生成,因此mtime只能精確到s,所以1s內生成的etag總是一樣,這樣就避免了使用強etag造成的 1s內頻繁的重新整理cache的情況。(貌似不用etag,僅僅使用last-modified就可以解決,但是這針對的僅僅是修改超級頻繁的情況,很多文 件可能同時也使用強etag驗證)。弱etag以w/開始,比如:w/」2e681a」

問題3、某些伺服器不能精確的得到檔案的最後修改時間;

解決辦法:生成etag,因為etag可以綜合inode,mtime和size,可以避免這個問題

HTTP協議快取策略深入詳解之etag妙用

etag是什麼 etag 是url的entity tag,用於標示url物件是否改變,區分不同語言和session等等。具體內部含義是使伺服器控制的,就像cookie那樣。http協議規格說明定義etag為 被請求變數的實體值 另一種說法是,etag是乙個可以與web資源關聯的記號 token 典型...

通過http協議中的etag進行使用者追蹤

使用者追蹤是同過乙個唯一標識能定位到乙個使用者。例如a使用者訪問 生成乙個唯一cookie,隨後使用者請求都帶上這個cookie,那麼通過這個cookie就可以分析使用者的訪問或操作行為。通過瀏覽器通常進行使用者追蹤使用的常用手段如幾種,但不僅限於這幾種。除此之外還可以通過http 1.1中的eta...

HTTP協議快取策略深入詳解之ETAG妙用

etag是什麼 etag 是url的entity tag,用於標示url物件是否改變,區分不同語言和session等等。具體內部含義是使伺服器控制的,就像cookie那樣。http協議規格說明定義etag為 被請求變數的實體值 另一種說法是,etag是乙個可以與web資源關聯的記號 token 典型...