文對強緩存和弱緩存進行講解:
為了展示強緩存和弱緩存
第一步:Ctrl + shift + delete將緩存給清除
將瀏覽器的數據給清空一下
這里的數據大小是83.4kB
在響應頭里面,會存在著ETag和Last-Modified資料
第一請求和第二請求,這里多了一個If-Modified,在弱緩存當中,從緩存中獲取數據,檢驗匹配是經過多次匹配,出現304指令,
200或者304指令意味著沒有發生變化
如果是強緩存這里根本不會產生數據,強緩存的特性是存儲在用戶的本地
瀏覽器緩存相關指令
expires指令
expires:該指令用來控制頁面緩存的作用。可以通過該指令控制HTTP應 答中的“Expires"和”Cache-Control"
expires 有兩種語法,一種是time,time是時間值,它默認是以秒來計數的
no-cache,無論緩存有沒有過期,都需要發送請求,檢驗緩存有沒有過期
max-age與expires的意思差不多,只不過有的沒有這個配置,
epoch會指定1970的時間,max是2037年的時間
具體配置流程:
vim ngnix.conf
為了方便對比,先將請求頭信息進行復制
之后在conf配置文件下配置
location ~ .*\.(html|js|css|png) $ {
}
以html和js和css等結尾的資源,都走這個
寫成expiress 1000;的意思是緩存1000s
檢驗語法,重新加載
重新對jQuery.js中進行查看
現在相應頭多了一塊時間max-age=1000秒和Expires:Mon.27(Expires的意思是服務器的時間)
如果將配置expiress修改為-1000,改為了負數,在請求頭中出現了no-cache
如果將該值指定為max
它會出現一些時間,默認是以秒來分割的
這個max的值是10年的意思,意思是最大的緩存時間可以已達到10年
add_header指令
add_header指令是用來添加指定的響應頭和響應值。
語法 add_header name value [always];
位置存儲在http、server、location..
如果想要到web服務器直接獲取,不緩存,用no-store
不緩存的寫法配置,在配置文件中添加add_header Cache-Control no-store
現在就實現了弱緩存,第一次訪問了304kb數據,第二次就是83.5kb,實現了弱緩存了
Web 緩存是可以自動保存常見文檔副本的 HTTP 設備。當 Web 請求抵達緩存時, 如果本地有“已緩存的”副本,就可以從本地存儲設備而不是原始服務器中提取這 個文檔。
一個緩存從接收到請求到做出響應,大概可以分為如下7個步驟:
項目中,我們主要使用緩存來存儲html、css、js、img等靜態資源,一般不會去存儲動態資源,因為對動態資源的緩存會對數據實時性造成影響
強緩存是當我們訪問URL的時候,不會向服務器發送請求,直接從緩存中讀取資源,但是會返回200的狀態碼。
我們第一次進入頁面,請求服務器,然后服務器進行應答,瀏覽器會根據response Header來判斷是否對資源進行緩存,如果響應頭中expires、pragma或者cache-control字段,代表這是強緩存,瀏覽器就會把資源緩存在memory cache 或 disk cache中。
第二次請求時,瀏覽器判斷請求參數,如果符合強緩存條件就直接返回狀態碼200,從本地緩存中拿數據。否則把響應參數存在request header請求頭中,看是否符合協商緩存,符合則返回狀態碼304,不符合則服務器會返回全新資源。
這是 http1.0 時的規范;它的值為一個絕對時間的GMT格式的時間字符串,如Mon, 10 Jun 2022 21: 31 :12 GMT,如果發送請求的時間在expires之前,那么本地緩存始終有效,否則就會發送請求到服務器來獲取資源。
Expires過度依賴本地時間,如果本地與服務器時間不同步,就會出現資源無法被緩存或者資源永遠被緩存的情況。所以,Expires字段幾乎不被使用了
上面我們提到了Expires有個缺點,當客戶端本地時間和服務器時間不一致時會產生誤差,瀏覽器會直接向服務器請求新的資源,為了解決這個問題,在http1.1規范中,提出了cache-control字段,且這個字段優先級高于上面提到的Expires,值是相對時間。
上面提到的強緩存都是由本地瀏覽器在確定是否使用緩存,當瀏覽器沒有命中強緩存時就會向瀏覽器發送請求,驗證協商緩存是否命中,如果緩存命中則返回304狀態碼,否則返回新的資源數據。
協商緩存(也叫對比緩存)是由服務器來確定資源是否可用,這將涉及到兩組字段成對出現的,在瀏覽器第一次發出請求時會帶上字段(Last-Modified或者Etag),則后續請求則會帶上對于的請求字段(if-modified-since或者if-none-Match),若響應頭沒有Last-Modified或者Etag,則請求頭也不會有對應的字段
const http = require('http');
const fs = require('fs');
http.createServer((req,res)=>{
if(req.url === 'test.png'){
const data = fs.readFileSync('./test.png');
const {mtime} = fs.statSync('./test.png');
const temp = req.headers['if-modified-since'];
if(temp === mtime.toUTCString()){
res.statusCode = 304;
res.end();
return;
}
res.setHeader('last-modified',mtime.toUTCString());
res.setHeader('Catch-Control','no=cache');
res.end(data);
}else{
res.end(fs.readFileSync('./test.html'));
}
})
const http = require('http');
const fs = require('fs');
const etag = require('etag');
http.createServer((req,res)=>{
if(req.url === 'test.png'){
const data = fs.readFileSync('./test.png');
const etagContent = etag(data);
const noMatch = req.headers['if-none-match'];
if(noMatch === etagContent){
res.statusCode = 304;
res.end();
return;
}
res.setHeader('etag',etagContent);
res.setHeader('Catch-Control','no=cache');
res.end(data);
}else{
res.end(fs.readFileSync('./test.html'));
}
})
畢清華:精選主力干將!
來源:微信公眾號:58本地服務終端技術
出處:https://mp.weixin.qq.com/s/-83N7RS1B6V_r5tcU2CyrA
試公司:
阿里
面試環節:
一面
問題:
說一說你對瀏覽器強緩存和協商緩存的理解
這里說的緩存是指瀏覽器(客戶端)在本地磁盤中對訪問過的資源保存的副本文件。
瀏覽器緩存主要有以下幾個優點:
瀏覽器緩存分為強緩存和協商緩存,兩者有兩個比較明顯的區別:
其中 from cache 會分為 from disk cache 和 from memory cache. 從內存中獲取最快,但是是 session 級別的緩存,關閉瀏覽器之后就沒有了。
請求流程
瀏覽器在第一次請求后緩存資源,再次請求時,會進行下面兩個步驟:
借用網上的一張圖片
強緩存
強緩存是根據返回頭中的 Expires 或者 Cache-Control 兩個字段來控制的,都是表示資源的緩存有效時間。
如果 Cache-Control 與 Expires 同時存在的話, Cache-Control 的優先級高于 Expires 。
協商緩存
協商緩存是由服務器來確定緩存資源是否可用。 主要涉及到兩對屬性字段,都是成對出現的,即第一次請求的響應頭帶上某個字, Last-Modified 或者 Etag,則后續請求則會帶上對應的請求字段 If-Modified-Since或者 If-None-Match,若響應頭沒有 Last-Modified 或者 Etag 字段,則請求頭也不會有對應的字段。
HTTP中并沒有指定如何生成 ETag,可以由開發者自行生成,哈希是比較理想的選擇。
為什么要有 Etag
HTTP1.1 中 Etag 的出現主要是為了解決幾個 Last-Modified 比較難解決的問題:
優先級
Cache-Control > expires > Etag > Last-Modified
用戶行為對緩存的影響
經過對qq、fire fox 、safari 、chrome 這幾個瀏覽器的訪問同一個頁面測試我發現,不同的瀏覽器在 F5 刷新的時候 ,同一個文件 qq 、fire fox 瀏覽器會返回 304 Not Nodified,在請求頭中不攜帶 Expires/Cache-Control; 而 chrome 和 safari 刷新的時候,會返回 200 from cache, 沒有真正發起請求,走強緩存。可見不同的瀏覽器反饋是不一致的,所以下面表格中"F5刷新"時 Expires/Cache-Control 會無效我認為是存在一定爭議的。
而 Ctrl + F5 強制刷新的時候,會暫時禁用強緩存和協商緩存。
如何設置強緩存和協商緩存
兩個示例
三級緩存原理(大白話)
最后總結一下瀏覽器的三級緩存原理:
原文:https://github.com/frontend9/fe9-interview/issues/29
*請認真填寫需求信息,我們會在24小時內與您取得聯系。