瀏覽器中的ETag標識

2021-08-14 18:01:11 字數 3149 閱讀 7120

etag[1] 是url的entity tag,用於標示url物件是否改變,區分不同語言和session等等。具體內部含義是使伺服器控制的,就像cookie那樣。

效能 聰明的伺服器開發者會把etags和get請求的「if-none-match」頭一起使用,這樣可利用客戶端(例如瀏覽器)的快取。因為伺服器首先產生etag,伺服器可在稍後使用它來判斷頁面是否已經被修改。本質上,客戶端通過將該記號傳回伺服器要求伺服器驗證其(客戶端)快取。

其過程如下:

客戶端請求乙個頁面(a)。 伺服器返回頁面a,並在給a加上乙個etag。 客戶端展現該頁面,並將頁面連同etag一起快取。 客戶再次請求頁面a,並將上次請求時伺服器返回的etag一起傳遞給伺服器。 伺服器檢查該etag,並判斷出該頁面自上次客戶端請求之後還未被修改,直接返回響應304(未修改——not modified)和乙個空的響應體。

優勢 1、有些url是多語言的網頁,相同的url會返回不同的東東。還有不同的session有不同的cookie也就有不同的內容。這種情況下如果過 proxy,proxy就無法區分導致串門,只能簡單的取消cache功能。etag解決了這個問題,因為它能區分相同url不同的物件。

2、老的http標準裡有個last-modified+if-modified-since表明url物件是否改變。etag也具有這種功能,因為物件改變也造成etag改變,並且它的控制更加準確。etag有兩種用法 if-match/if-none-match,就是如果伺服器的物件和客戶端的物件id(不)匹配才執行。這裡的if-match/if-none- match都能一次提交多個etag。if-match可以在etag未改變時斷線重傳。if-none-match可以重新整理物件(在有新的etag時返回)。

3、etag中有種weak tag,值為 w/」***xx」。他宣告tag是弱匹配的,只能做模糊匹配,在差異達到一定閾值時才起作用。

4、etag對於cache cgi頁面很有用。特別是論壇,論壇有辦法為每個帖子頁面生成唯一的etag,在帖子未改變時,檢視話題屬性比較etag就能避免重新整理帖子,減少cgi操作和網路傳輸。比如論壇中看帖就返回etag,減少論壇負擔。

5、etag在不同url之間沒有可比性,也就是不同url相同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.(不要陷入到底使用誰的問題怪圈)

查了一下expires描述和上面說有的點衝突:

expires 頭指定了乙個日期/時間, 在這個日期/時間之後,http響應被認為是過時的;

無效的日期,比如 0, 代表著乙個過去的事件,即該資源已經過期了。

如果還有乙個 設定了 「max-age」 或者 「s-max-age」 指令的cache-control響應頭,那麼 expires 頭就會被忽略。

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需要放在」「內。

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

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

fileetag inode mtime size

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

etag」2e681a-6-5d044840」

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

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

etag」6」

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

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

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

瀏覽器Etag的原理

把last modified和etags請求的http報頭一起使用,這樣可利用客戶端 例如瀏覽器 的快取。因為伺服器首先產生last modified etag標記,伺服器可在稍後使用它來判斷頁面是否已經被修改。本質上,客戶端通過將該記號傳回伺服器要求伺服器驗證其 客戶端 快取。過程如下 etag ...

瀏覽器大戰中的搜狗瀏覽器

abc 智慧型狂拼 紫光華宇,其中簡體中文全拼和智慧型 abc智慧型對於語句的輸入支援有限,而智慧型狂拼和紫光華宇詞儘管可以根據本地詞頻來智慧型新增詞語但本身詞庫更新慢,使用搜狗輸入法的原因是它每次上網時都會自動更新一些流行的詞語,使我們輸入更方便了。其實對於瀏覽器,我很少在意的,也不經常換,我自己...

Vue獲取瀏覽器唯一標識

登陸時候可能需要向後台傳輸乙個唯一識別符號 具體實現思路如下 1 引入js 2 寫入 mounted let options console.log options fingerprint2.get options,function components 指紋 const murmur finger...