摘要:對(duì)于的緩存機(jī)制來說,策略體現(xiàn)在的頭部信息的字段上,而這些策略根據(jù)是否需要重新向服務(wù)器端發(fā)起請(qǐng)求可以分為強(qiáng)緩存和協(xié)商緩存兩大類。接下來就是要介紹,兩類緩存相關(guān)相關(guān)字段的控制實(shí)現(xiàn)了。
概述
緩存的重要性不言而喻,通過網(wǎng)絡(luò)請(qǐng)求資源緩慢并且降低了客戶端的用戶體驗(yàn),增添了服務(wù)端的負(fù)擔(dān)。很多短期之內(nèi)不會(huì)經(jīng)常發(fā)生變化的資源文件沒必要每次訪問都想服務(wù)端進(jìn)行數(shù)據(jù)請(qǐng)求,而緩存策略的使用就是為了改善客戶端的呈現(xiàn)時(shí)間,降低服務(wù)端的負(fù)擔(dān)。
對(duì)于HTTP的緩存機(jī)制來說,策略體現(xiàn)在HTTP的頭部信息的字段上,而這些策略根據(jù)是否需要重新向服務(wù)器端發(fā)起請(qǐng)求可以分為強(qiáng)緩存和協(xié)商緩存兩大類。接下來用UML時(shí)序圖的形式來呈現(xiàn)這兩大類緩存策略的大體過程。
Tips: Vscode 配合插件 plantUML畫(寫)UML圖很爽。相比之前用的ProcessOn拖拽的形式,你只需要熟悉plantUML的語法,在你的電腦上安裝一下java,Graphviz 的環(huán)境,不用操心樣式的展現(xiàn)UML真心舒服。下面的圖我就是用這個(gè)工具去畫的,很推薦。
強(qiáng)緩存
強(qiáng)緩存緊密聯(lián)系著一個(gè)緩存時(shí)間期限,當(dāng)瀏覽器請(qǐng)求資源的時(shí)候會(huì)查看緩存中的資源是否存在并且確定該緩存的資源是否過了“保質(zhì)期”,若沒有超過保質(zhì)期則將取得緩存中的資源進(jìn)行下一步處理
協(xié)商緩存
可見協(xié)商緩存無論如何都會(huì)和服務(wù)器交互,比較強(qiáng)緩存稍微要復(fù)雜一點(diǎn),但是二者是相輔相成并且可以共同存在的,強(qiáng)緩存優(yōu)先級(jí)較高,意味著請(qǐng)求一個(gè)資源時(shí)會(huì)先比較強(qiáng)緩存的字段,如果命中則不會(huì)再執(zhí)行接下來的協(xié)商緩存的過程。
接下來就是要介紹,兩類緩存相關(guān)HTTP header相關(guān)字段的控制實(shí)現(xiàn)了。
細(xì)節(jié) 1.強(qiáng)緩存與強(qiáng)緩存相關(guān)的HTTP header 的字段有兩個(gè) Expires以及Cache-Control
Expires
expires 字段規(guī)定了緩存的資源的過期時(shí)間,在此時(shí)間之前,緩存中的資源都是有效的,該字段的 value 是一個(gè)格林威治時(shí)間格式(GMT)的時(shí)間,即世界標(biāo)準(zhǔn)時(shí)間,js 通過 new Date().toUTCString()可得到,形如 Tue, 27 Feb 2018 06:37:48 GMT。他的缺點(diǎn)很明顯,時(shí)間期限是服務(wù)器生成,存在著客戶端和服務(wù)器的時(shí)間誤差,固定時(shí)間,HTTP 1.0時(shí)的規(guī)范。相比較接下來介紹的cache-control優(yōu)先級(jí)較低。
cache-control
該字段的值(默認(rèn)為private):
其中最常用的值max-age單位為秒,對(duì)比expires體現(xiàn)著一個(gè)相對(duì)時(shí)間,即多少秒后這個(gè)強(qiáng)緩存機(jī)制下的緩存資源失效。
public和private區(qū)別在于是否有中間商賺差價(jià)(是否允許CDN代理服務(wù)器緩存)
需要注意的一點(diǎn)是該字段值定義為no-cache并不是說,不準(zhǔn)使用緩存,而是需要走接下來的優(yōu)先級(jí)相對(duì)較低的另一類--協(xié)商緩存。真正決定不用緩存內(nèi)的資源是將該值定義為no-store
2.協(xié)商緩存協(xié)商緩存是通過客戶端和服務(wù)端進(jìn)行HTTP通信時(shí),所在響應(yīng)頭和請(qǐng)求頭中互相表達(dá)“曖昧”的,相互通氣,互送緩存標(biāo)識(shí)。
Last-Modified 和 If-Modified-Since
第一次請(qǐng)求某一個(gè)資源時(shí),由于一定不會(huì)走緩存,所以服務(wù)器端會(huì)在資源的響應(yīng)頭中加上一個(gè)形如Last-Modified:Mon, 26 Feb 2018 06:37:41 GMT的字段告訴客戶端瀏覽器,這個(gè)資源上次最后修改的時(shí)間;刷新頁面再次請(qǐng)求,這時(shí)候的協(xié)商緩存會(huì)在請(qǐng)求頭中加上一個(gè)形如If-Modified-Since:Mon, 26 Feb 2018 06:37:41 GMT,字面翻譯就是,是否在上個(gè)“曖昧”時(shí)間后修改了,值毫無疑問是服務(wù)端上一次響應(yīng)給他的時(shí)間,讓服務(wù)器去判斷是否在此時(shí)間之后資源內(nèi)容發(fā)生了變化。
整個(gè)過程也很簡(jiǎn)單,最后的結(jié)果也很簡(jiǎn)短。如果服務(wù)端發(fā)現(xiàn)改變了資源,就伴著200的 statuscode 和新鮮的資源給到客戶端,若是沒有修改,304 Not Modified讓客戶端從緩存中取。
Etag 和 If-None-Match
同樣,第一次客戶端請(qǐng)求一個(gè)資源文件時(shí),服務(wù)端隨資源在響應(yīng)頭部中甩來一個(gè)字段 Etag ,形如ETag:W/"1823823287"該字段的值是該資源在服務(wù)器端的唯一標(biāo)識(shí),生成的Etag值的策略有服務(wù)端決定,總之是資源的一個(gè)唯一的標(biāo)識(shí)。資源發(fā)生變化則該值也發(fā)生變化。下一次客戶端請(qǐng)求同一個(gè)資源的時(shí)候,在請(qǐng)求頭將這次得到的值放在請(qǐng)求頭中一個(gè)叫 If-None-Match 的字段中甩給服務(wù)端。
整個(gè)過程也很簡(jiǎn)單,最后的結(jié)果也很簡(jiǎn)短。如果服務(wù)端發(fā)現(xiàn)改變了資源,就伴著200的 statuscode 和新鮮的資源給到客戶端,若是沒有修改,304 Not Modified讓客戶端從緩存中取。
上述兩個(gè)方式中,Etag 和 If-None-Match的優(yōu)先級(jí)要高于Last-Modified 和 If-Modified-Since,進(jìn)而會(huì)衍生出一個(gè)思考,二者相比功能相同,但是表達(dá)形式?jīng)Q定了 Etag 解決了 Last-Modified 存在的一些問題,比如Last-Modified 是比較時(shí)間,精確到秒,若是毫秒級(jí)的改變則沒法兼顧,存在著周期性更改的資源,然而有可能資源本身的內(nèi)容并沒有改變,那如果重新請(qǐng)求響應(yīng)意義并不是那么的大。所以不難理解Etag具有高優(yōu)先級(jí)有他的合理之處。
簡(jiǎn)單操練一下使用Node的Express框架能夠輕松的觀察到這些字段帶來的影響實(shí)驗(yàn)。接下來通過使用Express4.x依舊保留下來的中間件express.static搭建一個(gè)建議的靜態(tài)文件響應(yīng)服務(wù)器。
其中 public 文件夾里面放著一個(gè)主頁面和兩張不一樣的圖片用來改變
//app.js const express = require("express") const path = require("path") const app = express() app.use(express.static(path.join(__dirname, "public"), { etag: false, lastModified:false, cacheControl: false, setHeaders:function(res,path,stat) { res.set({ expires: new Date(Date.now() + 60000), }) } })) app.listen(3000, () => { console.log("App listening on port 3000!"); });
//index.htmlDocument Hello World
詳細(xì)的express.static的細(xì)節(jié)請(qǐng)參考文檔,這里不過多贅述。
之前我們提到過,expires這個(gè)選項(xiàng)是優(yōu)先級(jí)相比較其他的控制選項(xiàng),所以想要種 expires 觀察效果是記得向上述app.js一樣把其他的都關(guān)掉,因?yàn)樗麄兌际悄J(rèn)為 true的。
然后啟動(dòng)服務(wù)器,訪問3000端口,打開開發(fā)人員工具,你就會(huì)看到如下被種了expires的響應(yīng)頭了。
之后,你改變圖片的名稱,調(diào)換兩張圖片的名字,你就會(huì)發(fā)現(xiàn)在 expires 的時(shí)間到之前圖片都不會(huì)發(fā)生變化,并且可見,他是從緩存中取得
接下來,改變app.js
app.use(express.static(path.join(__dirname, "public"), { etag: false, maxAge:30000, lastModified:false, setHeaders:function(res,path,stat) { res.set({ expires: new Date(Date.now() + 600000), }) } }))
maxAge的單位是毫秒,此時(shí)由于優(yōu)先級(jí)的關(guān)系,覆蓋掉 expires 之后在30秒之內(nèi)交換圖片名稱,重新刷新瀏覽器將不會(huì)看到資源發(fā)生變化,知道maxAge的時(shí)間到。對(duì)應(yīng)的響應(yīng)頭如下:
繼續(xù)修改app.js:
app.use(express.static(path.join(__dirname, "public"), { etag: false, maxAge:30000, cacheControl: false, lastModified:true, }))
你需要?jiǎng)h掉對(duì)強(qiáng)緩存的設(shè)置,因?yàn)閺?qiáng)緩存的設(shè)置會(huì)比協(xié)商緩存被先執(zhí)行,同樣的操作你將看到接下來的響應(yīng)頭和請(qǐng)求頭。
隨后,你將上述優(yōu)先級(jí)最高的 Etag 字段改為 true,得到的響應(yīng)頭和請(qǐng)求頭信息如下:
此外你也會(huì)發(fā)現(xiàn)如下情況:
這種現(xiàn)象就解釋了,協(xié)商緩存雖然總是要訪問服務(wù)器,但是當(dāng)資源沒有變動(dòng)的時(shí)候,服務(wù)端只會(huì)返回帶著304狀態(tài)碼的很小的一個(gè)頭部,并不會(huì)像第一次攜帶文件資源那么大了。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/92999.html
摘要:上面的代碼沒用過因?yàn)槲沂枪潭▉砣拥臄?shù)據(jù),為什么這個(gè)壓縮方法叫采樣率壓縮是因?yàn)榕浜希全@取圖片的寬高這個(gè)過程就是取樣。 目錄介紹 01.如何計(jì)算Bitmap占用內(nèi)存 1.1 如何計(jì)算占用內(nèi)存 1.2 上面方法計(jì)算內(nèi)存對(duì)嗎 1.3 一個(gè)像素占用多大內(nèi)存 02.Bitmap常見四種顏色格式 2.1 什么是bitmap 2.2 Android常見是那種 2.3 常見四種顏色格式...
摘要:元素用于指定過濾器的完整的限定類名。除此之外,過濾器不會(huì)被調(diào)用。參數(shù)用于訪問后續(xù)過濾器。還可以為指定目標(biāo)資源為某個(gè),例如當(dāng)用戶訪問時(shí),會(huì)執(zhí)行名字為的,這時(shí)會(huì)執(zhí)行過濾器。防止中文亂碼過濾器項(xiàng)目使用框架時(shí)。 文章首發(fā)在CSDN博客,轉(zhuǎn)載請(qǐng)務(wù)必注明以下所有鏈接,否則考慮法律追究責(zé)任。 CSDN地址:http://blog.csdn.net/tzs_1041218129/article/det...
摘要:做個(gè)小小的延伸在這個(gè)栗子中,兩個(gè)對(duì)象都有一條相同的值,但這兩個(gè)對(duì)象卻不相等,為什么呢因?yàn)閮蓚€(gè)對(duì)象分別引用的是存放在堆內(nèi)存中的個(gè)不同的對(duì)象,故變量和的值引用地址也是不一樣的。 JavaScript中,有七種內(nèi)置類型:6種原始類型和引用類型,他們分別是: 6種原始類型(基本類型): 空值(null) 未定義(undefined) 布爾值(boolean) 數(shù)字(number) 字符串(s...
摘要:使用簽署免費(fèi)證書后端掘金本文操作在操作系統(tǒng)下完成,需要和超文本傳輸安全協(xié)議英語,縮寫,常稱為,紅黑樹深入剖析及實(shí)現(xiàn)后端掘金紅黑樹是平衡二叉查找樹的一種。 使用 Lets Encrypt 簽署免費(fèi) Https 證書 - 后端 - 掘金 本文操作在Linux操作系統(tǒng)下完成,需要Python和Nginx 超文本傳輸安全協(xié)議(英語:Hypertext Transfer Protocol Sec...
閱讀 3140·2021-11-19 09:40
閱讀 2437·2021-10-14 09:42
閱讀 1713·2021-09-22 15:34
閱讀 1450·2019-08-30 15:55
閱讀 784·2019-08-29 12:59
閱讀 418·2019-08-28 18:28
閱讀 1825·2019-08-26 13:42
閱讀 1531·2019-08-26 13:29