瀏覽器快取如何控制? && 在url框中回車、F5 和 Ctrl + F5的區別是什麼?

weixin_34293059發表於2017-02-24

第一部分: 瀏覽器快取如何控制?      

最近在做網站,但是不知道快取是什麼東西怎麼能行! 如何實現HTTP快取呢? 下面我們來一步一步的探尋實現機制把。

  方案一: 無快取

     說明: 瀏覽器向伺服器請求資源m.png, 然後伺服器響應請求--找到對應的m.png後傳送給瀏覽器。 之後,瀏覽器再次向伺服器請求m.png, 伺服器又發回了同樣的一張圖片....迴圈往復.....

   優點: 瀏覽器請求,伺服器響應,思路清楚簡單容易實現。   

   缺點 : 每次我都請求同樣的資源時, 伺服器也在不斷地響應,這是非常浪費頻寬的。   

  方案二:有快取-無更新

   說明: 同樣,瀏覽器向伺服器請求資源m.png,然後伺服器找到後傳送給瀏覽器,這時瀏覽器把m.png儲存在本地(快取), 這樣以後每次再請求m.png時就不需要向伺服器要了,直接從本地取就行了,但是下次這個m.png的內容換了呢?

   優點: 節省頻寬(顯然的,後續直接從本地取資源即可)。          

   缺點:  如果伺服器上的m.png內容改變,我就不能得到改變後的資源了,而是始終拿到本地的資源。

 

  方案三: 有快取-有更新

   說明:  瀏覽器向伺服器請求資源m.png,然後伺服器找到後傳送給伺服器,同時還附帶額外資訊---過期時間,如Expires: Friday,26 Feb 2017 10:11:22GMT。  然後瀏覽器將圖片和過期時間同時儲存在本地。 

       瀏覽器第二次向伺服器請求資源,這時它會先檢視過期事件是否已經達到,如果在過期事件之內,就直接使用本地快取(狀態304); 如果超出了這個過期時間,就重新向伺服器傳送請求,伺服器再次發回最新資源和最新的過期時間, 瀏覽器再次儲存...

    優點:  一方面可以在過期時間之內就可以不再重新請求資源,節省了頻寬;另一方面也不會像第二種方案一樣,而是可以得到新資源。

        缺點: 在過期時間之後就要重新請求資源,但是如果資源內容沒改變呢? 這次拿回的資源不就浪費了頻寬嗎?除此之外,這種時間格式複雜,容易比對出錯。

 

  方案四: 有快取-有更新-更新機制加強

   說明: 剛才的更新機制是傳送來過期時間,而現在伺服器在傳送資源給瀏覽器的時候不再傳送具體的時間,而是傳送一個Cache-Control,這裡可以包含各種資訊。如Cache-Control: max-age=300; 這種方式和上面方案類似, 只是時間過期使用數字,不容易出錯。另外Cache-Control還可以是下面的一些值:  

  • Public---表示伺服器傳送的資源可以被任何中間節點快取,如 Server -> proxy1 -> proxy2 -> Browser,proxy1 和 proxy2也可以快取資源,這樣,下次請求時proxy2就可以返回資源。
  • Private---表示伺服器傳送的資源不可以被任何中間節點快取。
  • no-cache---表示不使用Cache-Control的快取控制方式(強快取),而是使用Etag 或者 Last-Modified(協商快取)欄位來控制快取。
  • no-store---表示真正地不用快取方式(每次都請求最新的資源),Etah和Last-Modified也不用。
  • max-age---表示當前資源的有效時間(就是強制快取,用於替代HTTP1.0的Expires的方案)。

  優點 : 使用max-age更加容易比對,其他的幾個值使得快取機制更加強大。  缺點:同方案三,有可能導致浪費頻寬。

 

  方案五: 有快取-有更新-更新機制完美

   說明:為了解決方案四在300s後請求資源時得到了並未更新的資源而導致浪費頻寬的情況,我們在給瀏覽器返回m.png圖片時,不僅需要附加 Cache-Control: max-age=300; 再傳送一個ETag欄位,如 Etag:W/"e-dafdajio54fdaadf/q5w"。  然後瀏覽器將圖片和兩個附加資訊都儲存起來, 300s內請求資源時,就從本地取,300s後請求資源時就將之前拿到的ETag資訊隨著請求發出,伺服器接受到請求後先比對得到的ETag和伺服器處圖片當前的ETag,如果相同,則表示圖片內容沒變,就傳送訊息(不包含圖片,304);如果ETag改變,就傳送新的m.png並且再傳送一個新的Etag給瀏覽器儲存,那麼這時的max-age應該也是同樣需要更新的,如此迴圈往復......

      與Etag功能類似的是Last-Modified/if-Modified-Since ,當資源過期時(max-age超時),發現資源具有Last-Modified宣告(是瀏覽器接收到的資源最新被修改的時間),於是傳送請求時帶上If-Modified-Since(即剛才的Last-Modified的時間),web伺服器收到請求時,將If-Modeified-Since時間的資源與當前資源對比, 如果沒變, 就響應HTTP304,讓瀏覽器使用快取, 如果不是,就傳送新的資源。  

 

 

 

第二部分: 在url框中回車、F5 和 Ctrl + F5的區別是什麼?

  

不少同學問,不都是重新整理嗎?還有什麼區別?其實,還是有的。不同的方式會控制不同的快取策略

其中,在位址列按回車又分為兩種情況。一是請求的URI在瀏覽器快取中未過期,此時,使用Firefox的firebug外掛在瀏覽器裡顯示的HTTP請求訊息頭如下:

Host    192.168.3.174:8080
User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language    zh-cn,zh;q=0.5
Accept-Encoding    gzip, deflate
Accept-Charset    GB2312,utf-8;q=0.7,*;q=0.7
Connection    keep-alive

HTTP返回狀態顯示200 OK,但是,後臺Nginx伺服器的access.log並沒有找到該請求的記錄,說明請求並沒有真正提交到HTTP伺服器。而是被瀏覽器發現快取中還有 未過期的檔案,直接把請求攔截了,firebug裡面顯示所謂的“請求頭訊息”、“響應頭訊息”都是瀏覽器“偽造”的。這種重新整理,使用的網路流量是最小 的,可以說完全沒有,時間消耗也是最少的就像你找到一盒沒有過期的牛奶,覺得肯定沒有問題,誰都沒告訴就喝了。

二是請求的URI在瀏覽器快取中已過期,此時,firebug顯示的HTTP請求訊息頭如下:

Host    192.168.3.174:8080
User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language    zh-cn,zh;q=0.5
Accept-Encoding    gzip, deflate
Accept-Charset    GB2312,utf-8;q=0.7,*;q=0.7
Connection    keep-alive
If-Modified-Since    Mon, 04 Jul 2011 10:12:40 GMT

多了一行If-Modified-Since,後臺Nginx伺服器的access.log也找到了該請求的記錄,說明瀏覽器對這種情況的處理方法是:再 問一下伺服器,請求的URI在某個時間之後有沒有被修改過,而這個時間是由上次HTTP響應的Last-Modified決定的。伺服器鑑定之後,沒有修 改的話,返回304 Not Modified,瀏覽器收到後,從快取裡讀出內容;有修改的話,返回200 OK,並返回新的內容。這種情況,就像你找到一盒已經過期的牛奶,於是問別人,還能不能喝,如果別人說可以,你就把它喝了,如果別人說不行,那你得就另外 找一盒新鮮的牛奶。

至於F5重新整理,其HTTP請求訊息頭如下:

Host    192.168.3.174:8080
User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language    zh-cn,zh;q=0.5
Accept-Encoding    gzip, deflate
Accept-Charset    GB2312,utf-8;q=0.7,*;q=0.7
Connection    keep-alive
If-Modified-Since    Mon, 04 Jul 2011 10:12:40 GMT
Cache-Control    max-age=0

又多了一行Cache-Control: max-age=0,意思是說,我不管瀏覽器快取中的檔案過期沒有,都去伺服器詢問一下,相當於上次HTTP響應的Expires暫時失效。伺服器的響應 處理流程同上。這種情況,就像你找到一盒牛奶,沒有看它的有效期,直接就問別人能不能喝。

最後是Ctrl+F5重新整理,其HTTP請求訊息頭如下:

Host    192.168.3.174:8080
User-Agent    Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept    text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language    zh-cn,zh;q=0.5
Accept-Encoding    gzip, deflate
Accept-Charset    GB2312,utf-8;q=0.7,*;q=0.7
Connection    keep-alive
Pragma    no-cache
Cache-Control    no-cache

If-Modified-Since沒有了,Cache-Control換成了no-cache,此外Pragma行是為了相容HTTP1.0,作用與 Cache-Control: no-cache是一樣的。意思是,我不要快取中的檔案了,強制重新整理,直接到伺服器上重新下載,於是伺服器的響應處理與首次請求這個URI一樣,返回 200 OK和新的內容。這種重新整理,使用的網路流量是最大的,也是最耗時的。這就你雖然發現了一盒牛奶,但是把它扔掉了,直接去買一盒新的。

相關文章