導航:首頁 > 配伺服器 > 伺服器如何生成etag

伺服器如何生成etag

發布時間:2023-03-19 02:23:08

1. 靜態資源常用的一種緩存方式

http緩存分為強緩存和協商緩存。
強緩存並不會請求伺服器,同時響應碼會返回200。比如使用的配置cache-control:max-age=1200

在項目中緩存圖片等靜態資源常用的是協商緩存。
在第一次請求靜態資源首握的時候,伺服器會根據資源內容生成etag, 在響應頭里返回給瀏覽器,在下次請求的時候瀏覽器會在頭部配置If-None-Match,攜帶etag來向伺服器詢問資源是否發生改變。若是沒有發生改變會返回304,這樣瀏覽器就不會從伺服器重新獲取資源而是直接使用本地緩存。採用etag可以解決文件名沒有發生變化但是文件內容被修改的問題。

通常者謹慶會跟cache-control: no-cache 在一起配合使晌孫用。no-cache是指瀏覽器可以緩存響應,但是必須要向原始伺服器提交驗證請求。

參考:
https://www.imperva.com/learn/performance/cache-control/
https://blog.csdn.net/aimeimeiTS/article/details/105731709
https://www.zoo.team/article/http-cache
https://imweb.io/topic/5795dcb6fb312541492eda8c
https://aotu.io/notes/2016/09/22/http-caching/index.html

2. ETag詳細資料大全

HTTP協定規格說明定義ETag為「被請求變數的實體值」。另一種說法是,ETag是一個可以與Web資源關聯的記號(token)。典型的Web資源可以一個Web頁,但也可能是JSON或XML文檔。伺服器單獨負責判斷記號是什麼及其含義,並在HTTP回響頭中將其傳送到客戶端,以下是伺服器端返回的格式:ETag:"50b1c1d4f775c61:df3"客戶端的查詢更新格式是這樣的:If-None-Match : W / "50b1c1d4f775c61:df3"如果ETag沒改變,則返回狀態304然後不返回,這也和Last-Modified一樣。測試Etag主要在斷點下載時比較有用。

基本介紹

概念,性能,優勢,請求流程,作用,Apache,

概念

Etag 是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/"xxxxx"。他聲明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.(不要陷入到底使用誰的問題怪圈)

作用

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

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設定,比如設定成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。

3. 瀏覽器緩存和伺服器緩存

一、瀏覽器緩存 瀏覽器緩存即http緩存;瀏覽器緩存根據是否需要向伺服器重新發起HTTP請求將緩存過程分為兩個部分,分別是 強制緩存 和 協商緩存  。瀏覽器第一次請求資源的時候伺服器會告訴客戶端是否應該緩存資源,根據響應報文中HTTP頭的緩存標識,決定是否緩存結果,是則將請求結果和緩存標識存入瀏覽器緩存中。如下圖:1.強制緩存 :瀏覽器會對緩存進行查找,並根據一定的規則確定是否使用緩存。 強制緩存的緩存規則? HTTP/1.0 Expires 這個欄位是絕對時間,比如2018年6月30日12:30,然後在這個時間點之前的請求都會使用瀏覽器緩存,除非清除了緩存。 這個欄位的缺點就是只會同步客戶端的時間,這就有可能修改客戶端時間導致緩存失效。 HTTP/1.1 cache-Control       這個是1.1的時候替換Expires的,它會有幾種取值: public :所有內容都將被緩存(客戶端和代理伺服器都可緩存) private :所有內容只有客戶端可以緩存, Cache-Control的默認取值 no-cache :客戶端緩存內容,但是是否使用緩存則需要經過協商緩存來驗證決定 no-store :所有內容都不會被緩存,即不使用強制緩存,也不使用協商緩存 max-age=xxx (xxx is numeric) :緩存內容將在xxx秒後失效 比如max-age=500,則在500秒內再次請求會直接只用緩存。 優先性:cache-Control > Expires 如果同時存在,cache-Control會覆蓋Expires。 這個欄位的缺點就是: 如果資源更新的速度是秒以下單位,那麼該緩存是不能被使用的,因為它的時間單位最低是秒。 如果文件是通過伺服器動態生成的,那麼該方法的更新時間永遠是生成的時間,盡管文件可能沒有變化,所以起不到緩存的作用。上圖中瀏覽器緩存中存在該資源的緩存結果,並且沒有失效,就會直接使用緩存的內容。上圖中瀏覽器緩存中沒有該資源的緩存結果和標識,就會直接向伺服器發起HTTP請求。2.協商緩存: 瀏覽器的強制緩存失效後(時間過期),瀏覽器攜帶緩存標識請求伺服器,由伺服器決定是否使用緩存。 伺服器決定的規則? 控制協商緩存的欄位有 Last-Modified / If-Modified-Since 和 Etag / If-None-Match。 ①Last-Modified 是伺服器返回給瀏覽器的本資源的最後修改時間。 當下次再次請求的時候,瀏覽器會在請求頭中帶 If-Modified-Since ,即上次請求下來的 Last-Modified 的值, 然後伺服器會用這個值和該資源最後修改的時間比較,如果最後修改時間大於這個值,則會重新請求該資源,返回狀態碼200。 如果這個值和最後修改時間相等,則會返回304,告訴瀏覽器繼續使用緩存。 ② Etag 是伺服器返回的一個hash值。 當下次再次請求的時候,瀏覽器會在請求頭中帶 If-None-Match ,即上次請求下來的 Etag 值, 然後伺服器會用這個值和該資源在伺服器的 Etag 值比較,如果一致則會返回304,繼續使用緩存;如果不一致,則會重新請求,返回200。二、伺服器緩存 上面是一個簡單的流程圖: 用戶1訪問A頁面,伺服器解析A頁面返回給用戶1,同時在伺服器內存上做一定映射,把A頁面緩存在硬碟上面 用戶2訪問A頁面,伺服器直接根據內存上的映射找到對應的頁面緩存,直接返回給用戶2,這樣就減少了伺服器對同一頁面的重復解析 伺服器緩存和瀏覽器緩存的區別: 伺服器緩存是把頁面緩存到伺服器上的硬碟里,而瀏覽器緩存是把頁面緩存到用戶自己的電腦里Nginx伺服器  Nginx是一個高性能的HTTP和反向代理伺服器。具有非常多的優越性: 在連接高並發的情況下,Nginx是Apache伺服器不錯的替代品,Nginx在美國是做虛擬主機生意的老闆們經常選擇的軟體平台之一。 Nginx提供了expires、etag、if-modified-since指令來實現瀏覽器緩存控制。nginx -s reload#重新載入配置文件  nginx -s reopen#重新打開log文件  nginx -s stop#快速關閉nginx服務  nginx -s quit #優雅的關閉nginx服務,等待工作進程處理完所有的請求Nginx設置靜態文件的緩存過期時間  location ~.*\.(js|css|html|png|jpg)$ {   expires 3d; }  expires    3d;//表示緩存3天 expires    3h;//表示緩存3小時 expires    max;//表示緩存10年 expires    -1;//表示永遠過期。 如果設置為-1在js、css等靜態文件在沒有修改的情況下返回的是http 304,如果修改返回http 200 對於靜態資源會自動添加ETag,可以通過添加etag off指令禁止生成ETag。如果是靜態文件,那麼Last-Modified值為文件的最後修改時間。在開發調試web的時候,經常會碰到因瀏覽器緩存(cache)而經常要去清空緩存或者強制刷新來測試的煩惱,提供下apache不緩存配置和nginx不緩存配置的設置。在常用的緩存設置裡面有兩種方式,都是使用add_header來設置:分別為Cache-Control和Pragma。 location ~ .*\.(css|js|swf|php|htm|html )$ {   add_header Cache-Control no-store;   add_header Pragma no-cache;   } nginx gzip壓縮 使用 gzip 壓縮可以降低網站帶寬消耗,同時提升訪問速度。 主要在nginx服務端將頁面進行壓縮,然後在瀏覽器端進行解壓和解析, 目前大多數流行的瀏覽器都遲滯gzip格式的壓縮,所以不用擔心。 默認情況下,Nginx的gzip壓縮是關閉的,同時,Nginx默認只對text/html進行壓縮 gzip on; ersio #開啟gzip壓縮輸出 gzip_http_vn 1.0 ;#默認1.1 #其中的gzip_http_version的設置,它的默認值是1.1,就是說對HTTP/1.1協議的請求才會進行gzip壓縮 #如果我們使用了proxy_pass進行反向代理,那麼nginx和後端的upstream server之間是用HTTP/1.0協議通信的。 gzip_vary on ; #和http頭有關系,加個vary頭,給代理伺服器用的,有的瀏覽器支持壓縮,有的不支持, #所以避免浪費不支持的也壓縮,所以根據客戶端的HTTP頭來判斷,是否需要壓縮 gzip_comp_level 6; #設置gzip壓縮等級,等級越底壓縮速度越快文件壓縮比越小,反之速度越慢文件壓縮比越大 1-9 gzip_proxied any; #Ngnix作為反向代理的時候啟用 #expample:gzip_proxied no-cache; # off – 關閉所有的代理結果數據壓縮 # expired – 啟用壓縮,如果header中包含」Expires」頭信息 # no-cache – 啟用壓縮,如果header中包含」Cache-Control:no-cache」頭信息 # no-store – 啟用壓縮,如果header中包含」Cache-Control:no-store」頭信息 # private – 啟用壓縮,如果header中包含」Cache-Control:private」頭信息 # no_last_modified – 啟用壓縮,如果header中包含」Last_Modified」頭信息 # no_etag – 啟用壓縮,如果header中包含「ETag」頭信息 # auth – 啟用壓縮,如果header中包含「Authorization」頭信息 # any – 無條件壓縮所有結果數據 gzip_types text/html ;#壓縮的文件類型 #設置需要壓縮的MIME類型,非設置值不進行壓縮 #param:text/html|application/x-javascript|text/css|application/xml gzip_buffers 16 8k; #設置gzip申請內存的大小,其作用是按塊大小的倍數申請內存空間設置gzip申請內存的大小,其作用是按塊大小的倍數申請內存空間 #設置gzip申請內存的大小,其作用是按塊大小的倍數申請內存空間 # param1:int 增加的倍數 # param2:int(k) 後面單位是k # example: gzip_buffers 4 8k; # Disable gzip for certain browsers. gzip_disable 「MSIE [1-6].(?!.*SV1)」; #ie6不支持gzip,需要禁用掉ie6

4. 瀏覽器緩存策略

瀏覽器緩存策略分為兩種 強緩存 (本地緩存) 和 協商緩存 (弱緩存)。
瀏覽器在發請求前,先檢查強緩存,若沒有需要的內容(未命中),則發起請求判斷是否需要用弱緩存。

強緩存 是不發起請求,直接使用緩存內的內容的。瀏覽器將 js 、 css 、 image 、 font-family 等存到內存(存小文件)或者磁碟(存大文件)中,下次用戶再訪問的時候就從內存中取,以便提升性能。
協商緩存 需要往後台發請求, 通過判斷來決定是使用協商緩存。如果請求內容沒發生變化,則請求返回304(伺服器收到請求,但內容無變化),瀏覽器就用緩存內的內容。

如果伺服器返回的響應標頭中包含 Expires (時間戳),那麼客戶端發起請求的時間在 Expires 之前的話,就觸發強緩存。

伺服器在上一次響應請求時,返回一個帶 Last-Modified 的響應頭,值為一個時間戳,表示該資源最後一次在伺服器修改的時間。當客戶端再一次請求這個資源的時候, 請求頭就會帶上 If-Modified-Since ,值為上次伺服器發來的 Last-Modified , 伺服器收到後,就和該資源最後修改時間比對, 沒變化就返回304, 觸發協商緩存。
弊端 : 時間間隔最小為1s,如果請求的資源在1s內發生了改變,是可能會觸發協商緩存的, 導致無法獲取到最新的資源。

為解決間隔最小1s的問題, If-None-Match 和 Etag 就誕生了。 Etag 是由伺服器世孫廳生成的, 是每個資源搜隱的唯一標識字元串, 隨資源變化而改變。 判斷過程和http1.0的一致,請求的時候攜帶 If-None-Match ,然後伺服器比較這兩個值,沒變化就返回304, 觸發協商緩存。
弊端凱銷 : 佔用伺服器資源較多, 雖然准確度高,但是性能上不如 Last-Modified & If-Modified-Since 的方法。不過實際的影響不會很大, 基本上可以忽略不計。

即便我們沒有配置緩存策略,瀏覽器也會採用自己的演算法來緩存資源。

5. http緩存過程

註:http 緩存只能緩存 get 方式請求的資源
緩存是指 代理伺服器 客戶端本地磁碟 內保存的資源副本。利用緩存可減少對源伺服器的訪問,因此也就節省了通信流量和通信時間。
緩存伺服器是代理伺服器的一種,並歸類在緩存代理類型中。換句話說, 當代理轉發從伺服器返回的響應時,代理伺服器將會保存一份資源的副本
緩存伺服器的優勢在於利用緩存可避免多次從源伺服器轉發資源。因 此客戶端可就近從緩存伺服器上獲取資源,而源伺服器也不必多次處 理相同的請求了。

瀏覽器緩存分 強制緩存 協商緩存 ,分別使用的欄位前者是Expires和Cach-control,後者是 Etag 和 Last-modified。

Expires (http/1.0):設的是資源的過期時間(絕對時間),瀏覽器判斷這次請求的時候是不是超過這個日期,沒超的話就直接讀取緩存中的資源,不向伺服器發請求。

Pragma :欄位值為「no-cache」的時候,會通知客戶端不要對該資源讀緩存,即每次都得向伺服器發一次請求才行。但是這種禁用緩存的形式作用不是那麼太大:1. 僅有IE才能識別這段meta標簽含義,其它主流瀏覽器僅能識別「Cache-Control: no-store」的meta標簽。2. 在IE中識別到該meta標簽含義,並不一定會在請求欄位加上Pragma,但的確會讓當前頁面每次都發新請求,但是僅限頁面,頁面上的資源則不受影響。
如果Pragma和Expires一起出現的話,Pragma的優先順序是高的。

Cach-Control (http/1.1):緩存控制 示例:

Cache-Control 有三種屬性:緩沖能力、過期時間和二次驗證。

緩沖能力:

過期時間:

二次驗證:

Expires使用的是服務端時間,可能出現客戶端和服務端時間不同步,導致本地緩存無用或無法過期。
Max-Age使用的是客戶端本地時間的計算,不會出現這個問題,推薦Max-Age。
如果同時啟用了Cache-Control和Pragma ,Expires,Cache-Control優先順序高。

Last-Modified / If- Modified-Since (http/1.0):判斷資源最後修改時間,只要這個日期改變了就不使用緩存。瀏覽器的頭部是If- Modified-Since,服務端的是Last-Modified,如果兩個匹配,代表伺服器資源未改變,服務端不會返回資源實體,只返回頭部,通知瀏覽器使用緩存。
缺點:可能有些文件會周期性地改變日期,但是內容其實沒變,但是該欄位只判斷最後修改時間,
E-tag / If-None-Match (http/1.1):Etag 是伺服器針對請求的資源文件生成的唯一標識,只要文件內容沒變化,則Etag值不變,克服了 Last-Modified / If- Modified-Since 的缺點。瀏覽器的頭部是If-None-Match,服務端的是E-tag,如果兩個匹配,代表內容未改變,通知瀏覽器使用緩存。
Etag 缺點:不適用於分布式系統 ,因為每個伺服器上的 Etag 值不同。

如果同時帶有E-tag和Last-Modified,服務端優先檢查E-tag。

閱讀全文

與伺服器如何生成etag相關的資料

熱點內容
javame開發 瀏覽:376
python3偽裝瀏覽器 瀏覽:240
信息聯想伺服器專班是干什麼的 瀏覽:97
python獲取cpu個數 瀏覽:862
命令提示符查網速 瀏覽:227
對於某個理論演算法可以直接抄嗎 瀏覽:186
如何訪問ftp伺服器下載文件 瀏覽:390
呼蘭程序員吐槽剪輯 瀏覽:491
python計運算元網掩碼 瀏覽:57
加密u盤製作成iso鏡像 瀏覽:491
oppo大文件夾圖標 瀏覽:173
用cmd打開python文件 瀏覽:366
程序員磁碟知識 瀏覽:584
左摟右抱命令 瀏覽:931
法律大還是行政命令大 瀏覽:354
中國銀行手機app在哪裡刷臉 瀏覽:900
epidata如何編程 瀏覽:989
助眠解壓玩具電動 瀏覽:235
4k顯示器編程 瀏覽:267
什麼錯誤在編譯時會發現 瀏覽:700