免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      HTTP 的緩存為什么這么設(shè)計(jì)

      作為前端開發(fā),緩存是整天接觸的概念,面試必問、工作中也頻繁接觸到,可能大家對緩存的 header 記的比較熟了,可是大家有沒有思考過為什么 HTTP 的緩存控制要這么設(shè)計(jì)呢?

      首先,為什么要有緩存?

      網(wǎng)頁中的代碼和資源都是從服務(wù)器下載的,如果服務(wù)器和用戶的瀏覽器離得比較遠(yuǎn),那下載過程會(huì)比較耗時(shí),網(wǎng)頁打開也就比較慢。下次再訪問這個(gè)網(wǎng)頁的時(shí)候,又要重新再下載一次,如果資源沒有啥變動(dòng)的話,那這樣的重新下載就很沒必要。所以,HTTP 設(shè)計(jì)了緩存的功能,可以把下載的資源保存起來,再打開網(wǎng)頁的時(shí)候直接讀緩存,速度自然會(huì)快很多。

      而且,每個(gè)請求都要服務(wù)端做相應(yīng)的處理,比如解析 url,讀取文件,返回響應(yīng)等,而服務(wù)器能同時(shí)處理的請求是有上限的,也就是負(fù)載是有上限的,所以如果能通過緩存減少?zèng)]必要的資源的請求,就能解放服務(wù)器,讓它去處理一些更有意義的請求。

      綜上,為了提高網(wǎng)頁打開速度,降低服務(wù)器的負(fù)擔(dān),HTTP 設(shè)計(jì)了緩存的功能。

      那 HTTP 是怎么設(shè)計(jì)的緩存功能呢?

      如果讓大家設(shè)計(jì) HTTP 的緩存功能,大家會(huì)怎么設(shè)計(jì)呢?

      最容易想到的就是指定一個(gè)時(shí)間點(diǎn)了,到這個(gè)時(shí)間之前都直接用緩存,過期之后才去下載新的。

      HTTP 1.0 的時(shí)候也是這么設(shè)計(jì)的,也就是 Expires 的 header,它可以指定資源過期時(shí)間,到這個(gè)時(shí)間之前不去請求服務(wù)器,直接拿上次下載好被緩存起來的內(nèi)容,

      Expires: Wed, 21 Oct 2021 07:28:00 GMT

      但是這種設(shè)計(jì)有個(gè) bug,不知道大家能猜出來不。

      首先這個(gè)時(shí)間是指 GMT 時(shí)間,也就是會(huì)轉(zhuǎn)化為格林尼治那個(gè)時(shí)區(qū)的時(shí)間,不存在時(shí)區(qū)問題。

      服務(wù)端會(huì)把當(dāng)?shù)氐臅r(shí)間轉(zhuǎn)化為 GMT 時(shí)間,比如當(dāng)前是某個(gè)時(shí)間點(diǎn) xxx,想緩存的時(shí)間為 yyy,那 Expires 就設(shè)置為 xxx + yyy 的時(shí)間。

      如果瀏覽器的時(shí)間是準(zhǔn)確的,那轉(zhuǎn)化為 GMT 時(shí)間后應(yīng)該也是 xxx,所以緩存的時(shí)間就是 yyy。

      這是理想中的情況。

      但萬一瀏覽器的時(shí)間不準(zhǔn)呢?轉(zhuǎn)化為 GMT 時(shí)間之后就不是 xxx,那具體緩存的時(shí)間也就不是 yyy 了,這就是問題。

      所以,這個(gè)過期時(shí)間不能讓服務(wù)端來算,應(yīng)該讓瀏覽器自己算。

      這也是為什么在 HTTP 1.1 里面改為了 max-age 的方式:

      Cache-Control: max-age=600

      上面就代表資源緩存 600 秒,也就是 10 分鐘。

      讓瀏覽器來自己算啥時(shí)候過期,也就沒有 Expires 的問題了。(這也是為什么同時(shí)存在 max-age 和 Expires 會(huì)用 max-age 的原因)

      當(dāng)然,不同的資源會(huì)有不同的 max-age,比如打開 b 站首頁你會(huì)看到不同資源的 max-age 是不同的:

      圖片

      比如一些庫的 js 文件就設(shè)置了 31536000,也就是 1 年后過期,因?yàn)橐话阋膊粫?huì)變,以年為單位沒啥問題。

      而業(yè)務(wù)的 js 文件設(shè)置了 600,也就是 10 分鐘過期,業(yè)務(wù)代碼經(jīng)常會(huì)變動(dòng)嘛。

      細(xì)心的同學(xué)可能會(huì)發(fā)現(xiàn)之前都是 key: value 形式的 header,現(xiàn)在咋變成了 key: k1=v1,k2=v2 的形式了呢?

      沒錯(cuò),這也是 HTTP 1.1 做的設(shè)計(jì),他們想把緩存相關(guān)的 header 都集中到一起,所以就包了一層,都放在 Cache-Control 的 header 里。

      所以名字上也就不一樣了,Expires: xxx 這種叫做消息頭(header),而 Cache-Control: max-age=xxx 里面的 max-age 叫做指令(directive)。

      好了,改成 max-age 之后,瀏覽器就會(huì)在本地計(jì)算出的過期時(shí)間就去下載新的資源了。

      但是這樣就行了么?

      只是到了過期時(shí)間,但是資源并不一定有變化呀,那再下載一次同樣的內(nèi)容還是很沒必要。

      所以要和服務(wù)端確認(rèn)下是否內(nèi)容真的變了,變了的話就重新下載,否則的話就不用再下載了,有這樣一個(gè)協(xié)商的過程。

      所以 HTTP 1.1 又設(shè)計(jì)了協(xié)商緩存的 header。

      我們說到資源過期了,瀏覽器要和服務(wù)端確認(rèn)下是否有更新,怎么判斷資源過期呢?

      比較容易想到可以通過文件內(nèi)容的 hash,也可以通過最后修改時(shí)間,這倆分別叫 Etag 和 Last-Modified:

      圖片

      服務(wù)端返回資源的時(shí)候就會(huì)帶上這倆 header。

      那在 max-age 時(shí)間到了的時(shí)候,就可以帶上 etag 和 last-modified 就請求服務(wù)器,問下是否資源有更新。

      帶上 etag 的 header 叫做 If-None-Match:

      If-None-Match: “bfc13a64729c4290ef5b2c2730249c88ca92d82d”

      帶上 last-modified 時(shí)間的叫做 If-Modified-Since:

      If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT

      服務(wù)端判斷下如果資源有變化,那就返回 200,并在響應(yīng)體帶上新的內(nèi)容,瀏覽器就用這份新下載的資源。

      如果沒有變化,那就返回 304,響應(yīng)體是空的,瀏覽器會(huì)直接讀緩存。

      這樣多了一個(gè)協(xié)商的階段,那在本地緩存過期但是服務(wù)端改資源沒有變化的時(shí)候就能避免重復(fù)的下載。

      那如果文件確定不會(huì)變,不需要協(xié)商的話,怎么告訴瀏覽器呢?可以用 immutable 的 directive 來告訴瀏覽器,這個(gè)資源就是不變的,不用協(xié)商了。這樣就算緩存過期了也不會(huì)發(fā)驗(yàn)證的 header(If-None-Match 和 If-Modified-Since):

      Cache-control: immutable

      我們前面講了 HTTP 1.1 改成了 Cache-control: k1=v1,k2=v2 的形式,那除了 max-age 還有啥其他的 directive 呢?

      前面我們講的都是瀏覽器的緩存控制,但請求從瀏覽器到服務(wù)器的過程中,中間可能經(jīng)過很多層代理。

      代理服務(wù)器的緩存怎么控制?

      瀏覽器里的緩存都是用戶自己的,叫做私有緩存,而代理服務(wù)器上的緩存大家都可以訪問,叫做公有緩存。

      如果這個(gè)資源只想瀏覽器里緩存,不想代理服務(wù)器上緩存,那就設(shè)置 private,否則設(shè)置 public:

      比如這樣設(shè)置就是資源可以在代理服務(wù)器緩存,緩存時(shí)間一年(代理服務(wù)器的 max-age 用 s-maxage 設(shè)置),瀏覽器里緩存時(shí)間 10 分鐘:

      Cache-control:public, max-age=600,s-maxage:31536000

      這樣設(shè)置就是只有瀏覽器可以緩存:

      Cache-control: private, max-age=31536000

      而且,緩存過期了就完全不能用了么?

      不是的,其實(shí)也想用過期的資源也是可以的,有這樣的指令:

      Cache-control: max-stale=600

      stale 是不新鮮的意思。請求里帶上 max-stale 設(shè)置 600s,也就是說過期 10 分鐘的話還是可以用的,但是再長就不行了。

      Cache-control: stale-while-revalidate=600

      也可以設(shè)置 stale-while-revalidate,也就是說在和瀏覽器協(xié)商還沒結(jié)束的時(shí)候,就先用著過期的緩存吧。

      Cache-control: stale-if-error=600

      或者設(shè)置 stale-if-error,也就是說協(xié)商失敗了的話,也先用著過期的緩存吧。

      所以說,max-age 的過期時(shí)間也不是完全強(qiáng)制的,是可以允許過期后用一段時(shí)間的。

      那如果我想強(qiáng)制在緩存還沒協(xié)商完的時(shí)候不用過期的緩存怎么辦呢?

      用這個(gè)指令 must-revalidate:

      Cache-Control: max-age=31536000, must-revalidate

      名字上就可以看出來,就是緩存失效了的話,必須等驗(yàn)證結(jié)束,中間不能用過期的緩存。

      可能有的同學(xué)會(huì)有疑問,緩存不都是自己設(shè)置的么,咋還一個(gè)允許過期,一個(gè)禁止過期呢?

      自己會(huì)同時(shí)用這兩種和自己玩么?

      自己肯定不會(huì),但是 CDN 廠商可能會(huì)呀,想禁止這種用過期緩存的行為,就可以設(shè)置這個(gè) must-revalidate 指令。

      最后,HTTP 當(dāng)然也支持禁止緩存,也就是這樣:

      Cache-control: no-store

      設(shè)置了 no-store 的指令就不會(huì)緩存文件了,也就沒有過期時(shí)間和之后的協(xié)商過程。

      如果允許緩存,但是需要每次都協(xié)商下的話就用 no-cache:

      Cache-control: no-cache

      可能有的同學(xué)對 no-cache 和 must-revalidate 的區(qū)別比較迷糊,我們理一下:

      no-cache 相當(dāng)于禁掉了強(qiáng)緩存,每次都要協(xié)商下,而 must-revalidate 只是在強(qiáng)緩存過期之后,禁止掉了用過期的緩存的過程,強(qiáng)制必須協(xié)商。

      至此,http 的緩存設(shè)置我們就講完了,來總結(jié)一下:

      總結(jié)

      緩存能加快也面的打開速度,也能減輕服務(wù)器壓力,所以 HTTP 設(shè)計(jì)了緩存機(jī)制。

      HTTP 1.0 的時(shí)候是使用 Expires 的 header 來控制的,指定一個(gè) GMT 的過期時(shí)間,但是當(dāng)瀏覽器時(shí)間不準(zhǔn)的時(shí)候就有問題了。

      HTTP 1.1 的時(shí)候改為了 max-age 的方式來設(shè)置過期時(shí)間,讓瀏覽器自己計(jì)算。并且把所有的緩存相關(guān)的控制都放到了 Cache-control 的 header 里,像 max-age 等叫做指令。

      緩存過期后,HTTP 1.1 還設(shè)計(jì)了個(gè)協(xié)商階段,會(huì)分別通過 If-None-Match 和 If-Modified-Since 的 header 帶資源的 Etag 和 Last-Modied 到服務(wù)端問下是否過期了,過期了的話就返回 200 帶上新的內(nèi)容,否則返回 304,讓瀏覽器拿緩存。

      除了 max-age 的指令外,我們還學(xué)了這些指令:

      public:允許代理服務(wù)器緩存資源

      s-maxage:代理服務(wù)器的資源過期時(shí)間

      private:不允許代理服務(wù)器緩存資源,只有瀏覽器可以緩存

      immutable:就算過期了也不用協(xié)商,資源就是不變的

      max-stale:過期了一段時(shí)間的話,資源也能用

      stale-while-revalidate:在驗(yàn)證(協(xié)商)期間,返回過期的資源

      stale-if-error:驗(yàn)證(協(xié)商)出錯(cuò)的話,返回過期的資源

      must-revalidate:不允許過期了還用過期資源,必須等協(xié)商結(jié)束

      no-store:禁止緩存和協(xié)商

      no-cache:允許緩存,但每次都要協(xié)商

      雖然 HTTP 緩存相關(guān)的指令還是挺多的,但是都是圍繞 max-age 和過期后的協(xié)商來設(shè)計(jì)的,思路理清的話,還是很容易就能記住的。

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
      (0)
      用戶投稿
      上一篇 2022年6月28日 00:45
      下一篇 2022年6月28日 00:45

      相關(guān)推薦

      • 時(shí)間只是人類的錯(cuò)覺?

        首先提出一個(gè)概念:時(shí)間是什么 我們每天都能看到,太陽照常升起,樹葉隨風(fēng)搖動(dòng),馬路上來來往往的車輛和人群。萬事萬物都在運(yùn)動(dòng)和變化,因此人類設(shè)計(jì)出時(shí)間概念來幫助理解我們各類行為變化和運(yùn)…

        2022年8月16日
      • 為什么大多數(shù)有錢人不愿意跟窮人交流?

        和底層人談感情和道德,和中等人談邏輯和利益,和上層人談理想和未來。 最蠢的事不外乎和底層人講邏輯,和中層人談理想,和上層人談感情。 這三個(gè)群體兩兩之間不可能有真正的共同話題 最好的…

        2022年4月29日
      • 澳洲簽證:600旅游簽證,幫父母來澳洲團(tuán)聚

        最近很多關(guān)于父母旅游簽的咨詢,今天就為大家寫一篇。 很多網(wǎng)友移民澳洲定居多年,但是父母并沒有來過澳洲。疫情前還好,因?yàn)?,2年都會(huì)回去看一下父母,但是這次不一樣了,一個(gè)疫情就是兩年…

        2022年8月8日
      • 每個(gè)人心中都有一個(gè)“如果的世界”- 童書新品2022年9月

        每期會(huì)對圖書進(jìn)行簡單分類,便于讀者找到自己感興趣的書。本期的分類為圖畫書、科普百科和橋梁書。需要購買這些書的朋友可留意每本書的品牌方,去各大平臺的品牌自營店購買正版圖書。 童書市場…

        2022年9月24日
      • emo時(shí)的話語

        要的自取(謝謝關(guān)注) 1.我emo了,有一瞬間我想過死亡。 2.情緒可以控制,但眼淚不會(huì)撒謊。 3.很多人微笑,明知道虛偽卻還強(qiáng)擠著笑容。 4.成年人的情緒崩潰無法隨心所欲,不能當(dāng)…

        2022年6月16日
      • 有沒有家長入過網(wǎng)課的坑,特別是現(xiàn)在幾元幾節(jié)體驗(yàn)課?

        我現(xiàn)在帶的一個(gè)學(xué)生在這個(gè)暑假報(bào)的猿輔導(dǎo),6次課,每次課2個(gè)小時(shí),把蘇教版八年級上冊的內(nèi)容已經(jīng)全部學(xué)完。學(xué)生在上我的課的時(shí)候說,軸對稱圖形這章內(nèi)容他已經(jīng)學(xué)完了。我看他胸有成竹的表情,…

        2022年4月19日
      • SpringBoot項(xiàng)目中實(shí)現(xiàn)MySQL讀寫分離

        1、MySQL主從復(fù)制 但我們仔細(xì)觀察我們會(huì)發(fā)現(xiàn),當(dāng)我們的項(xiàng)目都是用的單體數(shù)據(jù)庫時(shí),那么就可能會(huì)存在如下問題: 讀和寫所有壓力都由一臺數(shù)據(jù)庫承擔(dān), 壓力大 數(shù)據(jù)庫服務(wù)器磁盤損壞則 …

        2022年7月10日
      • 成年人的無奈

        中年人的生活是可悲的,尤其是中年人的生活更是可悲的。每一分錢都恨不得分成兩半花,每當(dāng)給自己消費(fèi)的時(shí)候都會(huì)掂量掂量,該不該給自己花。就拿給自己配一臺電腦來說吧,事情的起因是我兩年前買…

        2022年7月24日
      • 正式簽約!男籃新星加盟新疆隊(duì),投奔阿的江,能否證明自己?

        最近一段時(shí)間,有關(guān)混血球員馮傲的去向引起了球迷的關(guān)注,因?yàn)樗鲃?dòng)放棄了前往美國訓(xùn)練打球的機(jī)會(huì),隨后他父親表示會(huì)加盟CBA球隊(duì)。等待了幾天之后,馮傲方面正式宣布加盟新疆男籃,并且球隊(duì)…

        2022年8月9日
      • 無論如何,還是要繼續(xù)

        終于從乃村出來了,這一篇文字拖的時(shí)間夠長,兩個(gè)月之久,一天一天的。這一篇,文字夠長,圖片也夠多,來來回回的,怎么去敘寫也好幾種方式的選擇,最終,成文了,也就都塵埃落定了,其實(shí)在它還…

        2022年9月14日

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息