<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Terry.Li-彬

    虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
    我們都知道,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,可以避免這個問題
    posted on 2010-09-26 23:03 禮物 閱讀(544) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。

    網站導航:
     
    主站蜘蛛池模板: 中文日本免费高清| 四虎在线免费视频| 亚洲综合久久成人69| 女人18毛片特级一级免费视频| 在线精品自拍亚洲第一区| 亚洲av无码成人黄网站在线观看| 动漫黄网站免费永久在线观看| 一级A毛片免费观看久久精品| 亚洲网址在线观看你懂的| 国产精品国产自线拍免费软件| 中文日本免费高清| 亚洲成a∧人片在线观看无码| 精品亚洲永久免费精品| 性盈盈影院免费视频观看在线一区| 成人A毛片免费观看网站| 亚洲中文字幕AV在天堂| 亚洲中文字幕无码爆乳AV| 最新中文字幕免费视频| 久久国产精品成人免费| 国产亚洲Av综合人人澡精品| 亚洲第一页在线播放| 亚洲欧洲国产精品香蕉网| 热久久精品免费视频| 最近中文字幕高清免费中文字幕mv| 黄色一级毛片免费| 亚洲最大的成人网| 亚洲视频一区在线观看| 国产综合亚洲专区在线| 四虎影库久免费视频| 亚洲中文无码永久免费| 久久久久久一品道精品免费看| 美女隐私免费视频看| 亚洲看片无码在线视频| 亚洲精品视频专区| 亚洲国产a∨无码中文777| 亚洲国产一区视频| 国产大片51精品免费观看| 18禁无遮挡无码网站免费| 最近免费字幕中文大全视频| 99在线热播精品免费99热| 成人免费观看男女羞羞视频|