用了兩天的業余時間,研究了一下緩存的事情,不敢說完全掌握,還是把找的相關資料按照自己的理解整理一下~以供學習,俗話說,好腦子不如爛筆頭,跟哪位前輩的重復了,歡迎批評指導,話不說多,步入正題
我們說的緩存指的是可以自動保存常見http請求副本的http設備,有了緩存,我們便可以從本地(瀏覽器)獲取,而不需要在從服務器端更新了;
緩存的分類,網上眾說紛紜,但是大致有以下幾:,瀏覽器緩存,CDN緩存,數據庫緩存,代理服務器緩存;但本文說的是瀏覽器緩存.
`我們有時候有個明顯的感覺就是,打開某個網站的時候,第一次會感覺慢和卡,第二次會快得多;當然,沒有感覺到的話,也可能是網速比較好,感覺到了就是緩存再起作用,第一次請求的時候,下載的數據比較多,第二次往后有緩存(本地副本),就會節約響應時間,
下面列舉一下使用緩存(本文指的是瀏覽器緩存,下文不在贅述)的優點:
1,對用戶來說,節約流量,提高了體驗性能
2,對網站開發來說,節省帶寬,減少冗余的數據傳輸,另一方面,也降低服務器的壓力
一,緩存的示意圖如下:
第一次請求的時候是這樣的
也不需要過多的解釋了,畢竟第一次,啥都要從服務器端獲取
2.以后的請求如下圖所示
對着流程簡單說一下,首先會判斷是否有緩存,沒有的話,跟第一次一樣,去服務器獲取;
有的情況下,就要判斷緩存時間是否過期,過期了,還要到服務器獲取,
沒有過期,執行接下來的一步,向服務器發送帶有If-None-Match,判斷返回的值和ETag是否相等,相等,說明可用緩存,
不相等,向服務器發送帶有Ih-Modified-Since,判斷和Last-Modified(最后修改時間)兩者的時間大小,在決定是使用緩存還是更新.看的懵逼沒事,先記住大概流程,接下來一一講解
二.相關名詞解釋
1.如何判斷時候過期
原來用的是Expires策略,瀏覽器可以直接從瀏覽器緩存讀取數據,而無需再次請求,它的值對應一個GMT,來告訴瀏覽器資源緩存過期時間,如果還沒過該時間點則不發請求。
例如下面的例子,這是京東的首頁里找的一個,時間都干到2027年了,現在的時間是2017年7月20,肯定還沒到失效時間,so是304,使用本地緩存,也就是說在失效時間之內,一直使用緩存,除非把緩存刪了
但是這是http1.0的東西,現在使用的是http1.1的,這個可以忽略了因為這個是獲取的本地的時間,我們改動的話,會出現問題,現在都用Cache-control了
cache-control策略有的地方也叫新鮮度限值
這個和上面說的expires效果是一樣的,最大時間,
用來控制瀏覽器是否直接從瀏覽器緩存取數據還是重新發請求到服務器取數據。
只不過Cache-Control的選擇更多,設置更細致,如果同時設置的話,其優先級高於Expires。
Cache-Control可擁有如下值:
Public
指定響應會被緩存,並且在多用戶間共享。
Private
響應只作為私有的緩存(見下圖),不能在用戶間共享。如果要求HTTP認證,響應會自動設置為private。。緩存只開放給某些特定的用戶,比如服務器的用戶,其他用戶則不能緩存這些數據。
no-cache
指定不緩存響應,表明資源不進行緩存,
no-store
用於防止重要的信息被無意的發布。在請求消息中發送將使得請求和響應消息都不使用緩存,完全不存下來。
max-age
指示客戶端該端時間內緩存都是最新的。單位為秒,就是在這個時間內,不會請求數據了,一直用的就是緩存。比如:Cache-Control:max-age=3600 表示60分鍾之后過期,在這60分鍾期間不會更新。
min-fresh
指示客戶端希望獲取一個在小於指定的時間內被更新過的資源,單位為秒:例如:Cache-Control:min-fresh =120 。向服務器獲取2分鍾內被更新過的資源
max-stale
指示客戶端可以接收超出超時期間的響應消息。例如:Cache-Control:max-stale =3600 ,向服務器獲取超過緩存時間2分鍾的資源..
2.Etag和If-None-Match
下面說的東西,包括Etag和If-None-Match,是在緩存時間已經失效的情況下,即Cache-Control:mac-age = 0 的情況下,
會判斷Etag和If-None-Match兩者是否相等,ETag是根據實體內容生成的hash字符串,具體是對文件的索引節(INode),大小(Size)和最后修改時間(MTime)進行Hash后得到的,
如果If-None-Match返回的和Etag相等的話,就返回304,可以使用緩存的資源,文件沒有被改動.具體如下
3.Last-Modified和If-Modified-Since
在多說一下,這個也是在緩存時間已經失效,即Cache-Control:mac-age = 0 的情況下,而且上面的Etag和If-None-Match不相等的情況下;
Last-Modified指的是文件上一次被修改的時間(可以理解為服務器端的),, 會帶着 If-Modified-Since(本地的)返回的時間,,本地的時間大於等於服務器端的時間的花,說明資源沒有被改動過接着用緩存的,否則就要更新,從新發送web請求了,如果感覺拗口的話,貼一下參考的原話,
當資源過期時(也就是 Cache-Control:max-age=0,),發現資源具有Last-Modified聲明,則再次向web服務器請求時帶上頭 If-Modified-Since,表示請求時間。web服
務器收到請求后發現有頭If-Modified-Since 則與被請求資源的最后修改時間進行比對。若Last-Modified的時間較新,說明最后修改時間較新,說明資源又被改動過,則響應整
的資源重新從服務器讀取,而不是讀取緩存,返回200狀態嗎;若If-Modified-Since的時間比Last-Modified新或者相等,說明服務器的內容沒有更新,直接讀取緩存即可,
返回304狀態碼,告知瀏覽器繼續使用所保存的cache。
另外需要說明的是: cache-control .Etag和If-None-Match Etag和If-None-Match三者的權重是從左到右越來越小的;
還有一點需要說明的是,我們說的緩存~基本上都是GET方式的,像POST之類的通常情況下是不會進行緩存的;
說了這么多,緩存是好的,可以節約資源,減少服務器的壓力,但是,設置太長的緩存時間的話,又不能及時的更新資源,具體如何取舍把握,還要視具體情況再說.