作網站,不知道緩存是什麼東西怎麼能行! 如何實現HTTP緩存呢? 下面咱們來一步一步的探尋實現機制把。html
說明:瀏覽器向服務器請求資源m.png, 而後服務器響應請求--找到對應的m.png後發送給瀏覽器。 以後,瀏覽器再次向服務器請求m.png, 服務器又發回了一樣的一張圖片....循環往復.....web
優勢:瀏覽器請求,服務器響應,思路清楚簡單容易實現。 瀏覽器
缺點:每次都請求一樣的資源時,服務器也在不斷地響應,這是很是浪費帶寬的。 緩存
說明: 一樣,瀏覽器向服務器請求資源m.png,而後服務器找到後發送給瀏覽器,這時瀏覽器把m.png保存在本地(緩存), 這樣之後每次再請求m.png時就不須要向服務器要了,直接從本地取就好了,可是下次這個m.png的內容換了呢?服務器
優勢: 節省帶寬(顯然的,後續直接從本地取資源便可)。 網絡
缺點: 若是服務器上的m.png內容改變,我就不能獲得改變後的資源了,而是始終拿到本地的資源。app
說明: 瀏覽器向服務器請求資源m.png,而後服務器找到後發送給服務器,同時還附帶額外信息---過時時間,如Expires: Friday,26 Feb 2017 10:11:22GMT。 而後瀏覽器將圖片和過時時間同時保存在本地。 網站
瀏覽器第二次向服務器請求資源,這時它會先查看過時事件是否已經達到,若是在過時事件以內,就直接使用本地緩存(狀態304); 若是超出了這個過時時間,就從新向服務器發送請求,服務器再次發回最新資源和最新的過時時間, 瀏覽器再次保存...url
優勢: 一方面能夠在過時時間以內就能夠再也不從新請求資源,節省了帶寬;另外一方面也不會像第二種方案同樣,而是能夠獲得新資源。spa
缺點: 在過時時間以後就要從新請求資源,可是若是資源內容沒改變呢? 此次拿回的資源不就浪費了帶寬嗎?除此以外,這種時間格式複雜,容易比對出錯。
說明: 剛纔的更新機制是發送來過時時間,而如今服務器在發送資源給瀏覽器的時候再也不發送具體的時間,而是發送一個Cache-Control,這裏能夠包含各類信息。如Cache-Control: max-age=300; 這種方式和上面方案相似, 只是時間過時使用數字,不容易出錯。另外Cache-Control還能夠是下面的一些值:
優勢 : 使用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,讓瀏覽器使用緩存, 若是不是,就發送新的資源。
很多同窗問,不都是刷新嗎?還有什麼區別?其實,仍是有的。不一樣的方式會控制不一樣的緩存策略。
其中,在地址欄按回車又分爲兩種狀況。
(1)請求的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裏面顯示所謂的「請求頭消息」、「響應頭消息」都是瀏覽器「僞造」的。這種刷新,使用的網絡流量是最小 的,能夠說徹底沒有,時間消耗也是最少的。就像你找到一盒沒有過時的牛奶,以爲確定沒有問題,誰都沒告訴就喝了。
(2)請求的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和新的內容。這種刷新,使用的網絡流量是最大的,也是最耗時的。這就像你雖然發現了一盒牛奶,可是把它扔掉了,直接去買一盒新的。
參考:http://www.cnblogs.com/zhuzhenwei918/p/6437574.html