強緩存和協商緩存

1、瀏覽器緩存
1,第一次請求,無緩存請求過程
         
流程以下所示
第二次請求,有緩存請求的過程
          
 
流程以下圖所示
瀏覽器的緩存分爲二種,第一種的是強緩存,另一種是協商緩存
2 :強緩存
定義:強緩存在請求資源的時候,會從header裏面讀取是不是強緩存,在有效的時間時間期內,從緩存裏讀取不能從服務那裏讀取

介紹使用:javascript

expires,這是http1.0時的規範;它的值爲一個絕對時間的GMT格式的時間字符串,如Mon, 10 Jun 2015 21:31:12 GMT,若是發送請求的時間在expires以前,那麼本地緩存始終有效,不然就會發送請求到服務器來獲取資源html


cache-control:的含義和使用
可緩存性屬性說明
pubilc:http只要通過的地方都要進行緩存
privite:發出的瀏覽器端要進行緩存
no-cache:本地能夠有緩存,須要服務器驗證纔可使用
no-store:本地和服務器都沒有緩存
max-age=<seconds> :緩存的最大的時間
3,代碼案例分析:
1,簡單的建立一個服務
const http = require('http');
const fs = require('fs');
// 建立一個http服務
http.createServer((request, response) => {
console.log('request-url' + request.url);
if (request.url === '/') {
const html = fs.readFileSync('test.html', 'utf8');
response.writeHead(200, {
'Content-Type': 'text/html',
})
response.end(html);
}
if (request.url === '/script.js') {
// const html = fs.readFileSync('test.html', 'utf8');
response.writeHead(200, {
'Content-Type': 'text/javascript',
'Cache-control': 'max-age=200 ',
})
response.end('ffff');
}
}).listen(8888);
4,解決的方法呢:

上面說到,使用強緩存時,瀏覽器不會發送請求到服務端,根據設置的緩存時間瀏覽器一直從緩存中獲取資源,在這期間若資源產生了變化,瀏覽器就在緩存期內就一直得不到最新的資源,那麼如何防止這種事情發生呢?前端

經過更新頁面中引用的資源路徑,讓瀏覽器主動放棄緩存,加載新資源。java

前端經常後面加上版本號和一些hash值從新的讀取api

    

2、介紹協商緩存
    協商緩存都是由服務器來肯定緩存資源是否可用的,因此客戶端與服務器端要經過某種標識來進行通訊,從而讓服務器判斷請求資源是否能夠緩存訪問,這主要涉及到下面兩組header字段,這兩組搭檔都是成對出現的,即第一次請求的響應頭帶上某個字段(Last-Modified或者Etag),則後續請求則會帶上對應的請求字段(If-Modified-Since或者If-None-Match),若響應頭沒有Last-Modified或者Etag字段,則請求頭也不會有對應的字段
     
  1. Last-Modified/If-Modified-Since
    兩者的值都是GMT格式的時間字符串,具體過程:
    • 瀏覽器第一次跟服務器請求一個資源,服務器在返回這個資源的同時,在respone的header加上Last-Modified的header,這個header表示這個資源在服務器上的最後修改時間
    • 瀏覽器再次跟服務器請求這個資源時,在request的header上加上If-Modified-Since的header,這個header的值就是上一次請求時返回的Last-Modified的值
    • 服務器再次收到資源請求時,根據瀏覽器傳過來If-Modified-Since和資源在服務器上的最後修改時間判斷資源是否有變化,若是沒有變化則返回304 Not Modified,可是不會返回資源內容;若是有變化,就正常返回資源內容。當服務器返回304 Not Modified的響應時,response header中不會再添加Last-Modified的header,由於既然資源沒有變化,那麼Last-Modified也就不會改變,這是服務器返回304時的response header
    • 瀏覽器收到304的響應後,就會從緩存中加載資源
    • 若是協商緩存沒有命中,瀏覽器直接從服務器加載資源時,Last-Modified的Header在從新加載的時候會被更新,下次請求時,If-Modified-Since會啓用上次返回的Last-Modified值
  2. Etag/If-None-Match
    這兩個值是由服務器生成的每一個資源的惟一標識字符串,只要資源有變化就這個值就會改變;其判斷過程與Last-Modified/If-Modified-Since相似,與Last-Modified不同的是,當服務器返回304 Not Modified的響應時,因爲ETag從新生成過,response header中還會把這個ETag返回,即便這個ETag跟以前的沒有變化。

 三、既生Last-Modified何生Etag
  你可能會以爲使用Last-Modified已經足以讓瀏覽器知道本地的緩存副本是否足夠新,爲何還須要Etag呢?HTTP1.1中Etag的出現主要是爲了解決幾個Last-Modified比較難解決的問題:
  • 一些文件也許會週期性的更改,可是他的內容並不改變(僅僅改變的修改時間),這個時候咱們並不但願客戶端認爲這個文件被修改了,而從新GET;
  • 某些文件修改很是頻繁,好比在秒如下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改沒法判斷(或者說UNIX記錄MTIME只能精確到秒);
  • 某些服務器不能精確的獲得文件的最後修改時間。
這時,利用Etag可以更加準確的控制緩存,由於Etag是服務器自動生成或者由開發者生成的對應資源在服務器端的惟一標識符。
Last-Modified與ETag是能夠一塊兒使用的,服務器會優先驗證ETag,一致的狀況下,纔會繼續比對Last-Modified,最後才決定是否返回304

4,代碼案例瀏覽器

if (etag === '777') {
response.writeHead(304, {
'Content-Type': 'text/javascript',
'Cache-control': 'max-age=200000,no-cache',
'last-Modified': '123',
'Etag': '777',
})
response.end('');
} else {
response.writeHead(200, {
'Content-Type': 'text/javascript',
'Cache-control': 'max-age=200000,no-cache',
'last-Modified': '123',
'Etag': '777',
})
response.end('fffff');
}

 

3、強緩存與協商緩存的區別,能夠用下表來進行描述:緩存

 

  獲取資源形式 狀態碼 發送請求到服務器
強緩存  從緩存取  200(from cache) 否,直接從緩存取
協商緩存  從緩存取  304(not modified) 是,正如其名,經過服務器來告知緩存是否可用
相關文章
相關標籤/搜索