今天這1課,我們主要學習下cache(緩存)。
一、緩存分類
cache(緩存)分為客戶端緩存和服務端緩存
服務端緩存又分為 代理服務器緩存 和 反向代理服務器緩存(也叫網關緩存,比如 Nginx反向代理、Squid等),其實廣泛使用的 CDN (快播貌似就是用的這個)也是一種服務端緩存,目的都是讓用戶的請求走”捷徑“,并且都是緩存圖片、文件等靜态資源。
客戶端緩存一般指的是浏覽器緩存,浏覽器緩存控制機制有兩種:HTML Meta标簽 vs. HTTP頭信息。目的就是加速各種靜态資源的訪問,想想現在的大型網站,随便一個頁面都是一兩百個請求,每天 pv 都是億級别,如果沒有緩存,用戶體驗會急劇下降、同時服務器壓力和網絡帶寬都面臨嚴重的考驗。
本篇主要講http客戶端緩存機制
二、fiddler查看緩存
打開fiddler抓包,用浏覽器打開測試部落論壇:http://120.25.145.237/upload/forum.php
如果浏覽器是第一次打開網站(以前沒打開過這個論壇),抓包情況如下:
在http請求headers裡cache區域,有兩個參數,顯示no-cache
第一次請求後,我們再次刷新(F5)下這個頁面,抓包情況如下:
會看到左側區域,有很多304顯示(右側cache中已經有了參數)說明浏覽器已經使用了緩存數據
三、浏覽器請求流程圖
浏覽器第一次請求流程圖:
浏覽器再次請求時:
四、服務器如何判斷緩存是否過期
web服務器通過2種方式來判斷浏覽器緩存是否是最新的。
第一種, 浏覽器把緩存文件的最後修改時間通過 header ”If-Modified-Since“來告訴Web服務器。
第二種, 浏覽器把緩存文件的ETag, 通過header "If-None-Match", 來告訴Web服務器。
五、If-Modified-Since
用F5刷新當前頁面(找到/upload/data/cache...這項),會發現不管怎麼刷新,If-Modified-Since後面的請求時間都沒有變,并且If-Modified-Since時間大于response headers裡的Data時間,如下圖:
說明浏覽器緩存是最新的,服務器會返回304,告訴客戶端使用本地緩存就行了
六、If-None-Match和ETag
Etag:
1.ETag是Web服務端産生的,然後發給浏覽器客戶端。浏覽器客戶端是不用關心Etag是如何産生的。
2. ETag是實體标簽(Entity Tag)的縮寫, 根據實體内容生成的一段hash字符串(類似于MD5或者SHA1之後的結果),可以标識資源的狀态。 當資源發送改變時,ETag也随之發生變化。
3. ETag默認是對文件的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後得到的。
If-None-Match:當資源過期時(使用Cache-Control标識的max-age),發現資源具有Etage聲明,則再次向web服務器請求時帶上頭If-None-Match (Etag的值)。web服務器收到請求後發現有頭If-None-Match 則與被請求資源的相應校驗串進行比對,決定返回200或304。
當按F5再次刷新論壇主頁時,對比客戶端If-None-Match和服務端Etag值是一樣的,說明不用更新緩存。
七、為什麼使用ETag呢?
1. 某些服務器不能精确得到文件的最後修改時間, 這樣就無法通過最後修改時間來判斷文件是否更新了。
2. 某些文件的修改非常頻繁,在秒以下的時間内進行修改. Last-Modified隻能精确到秒。
3. 一些文件的最後修改時間改變了,但是内容并未改變。 我們不希望客戶端認為這個文件修改了
八、Ctrl F5
Ctrl F5是強制刷新頁面,明确告訴服務端,不使用緩存
可以再部落論壇主頁ctrl f5試試,左側請求區域不會看到304了
Pragma: no-cache的作用和Cache-Control: no-cache一模一樣。 都是不使用緩存。
Pragma: no-cache 是HTTP 1.0中定義的, 所以為了兼容HTTP 1.0. 所以會同時使用Pragma: no-cache和Cache-Control: no-cache
九、浏覽器設置不使用緩存
打開IE。點擊工具欄上的, 工具->Internet選項->常規->浏覽曆史記錄 設置. 選擇“從不”。然後保存。
然後點擊“删除” 把Internet臨時文件都删掉 (IE緩存的文件就是Internet臨時文件)。
十、回車刷新、F5刷新、Ctrl F5刷新區别?
看到這裡有不少小夥伴要懷疑了,這三種刷新還有區别麼,不看不知道,一看吓一跳,區别還挺大哦。
回車刷新:可以先清空fiddler頁面的所有請求(命令行輸入cls,回車),然後在部落論壇首頁,回車查看請求結果,會發現隻有16條左右請求發送出去。而且幾乎沒有圖片的請求,這是因為請求時會先檢查本地是不是緩存了請求的圖片,如果有緩存而且沒有過期(過期可以通過該圖片請求的header查看),他就不會發出這個圖片request。
F5刷新:f5刷新比enter略慢,為什麼呢,因為他還是把所有請求(大概70多條)都發給了server,隻是在request裡的header裡有cache信息,服務器判斷還沒有過期,就直接返回304not modified,在fiddler裡看就是這些304的請求都為灰色。因為直接返回304這樣的信息,而不是圖片等内容,他比ctrl f5快,但是比enter慢,因為他還是把所有請求都發了一遍,比enter的不發請求自然是慢的。
Ctrl F5刷新:這個就要慢了,應為所有的請求都是重新發送,重新從server讀取内容,一點cache都沒有讀。為了防止在server的cache裡讀取,在ctrl f5刷新時,在request header 裡會加pragma:no-cache cache control:no-cache。這兩個就是告訴服務器到浏覽器中間的所有節點,沒有cache,看到這個中間節點也不查自己的cache,保證請求都是從server獲得的。
如果你對這三種刷新方式已經很清楚了,能清楚說明他們的區别,說明http的緩存方式,已經基本掌握了。
十一、緩存是開發最大的敵人
先說說緩存的好處:
1. 減少了冗餘的數據傳輸,節省了網費。
2. 減少了服務器的負擔, 大大提高了網站的性能
3. 加快了客戶端加載網頁的速度
當然往往BUG的産生,都是因為緩存處理不當導緻的。
你清空下緩存試試,然後bug就不見了!
,