在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    HTTP 的緩存為什么這么設計

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

    首先,為什么要有緩存?

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

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

    綜上,為了提高網(wǎng)頁打開速度,降低服務器的負擔,HTTP 設計了緩存的功能。

    那 HTTP 是怎么設計的緩存功能呢?

    如果讓大家設計 HTTP 的緩存功能,大家會怎么設計呢?

    最容易想到的就是指定一個時間點了,到這個時間之前都直接用緩存,過期之后才去下載新的。

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

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

    但是這種設計有個 bug,不知道大家能猜出來不。

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

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

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

    這是理想中的情況。

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

    所以,這個過期時間不能讓服務端來算,應該讓瀏覽器自己算。

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

    Cache-Control: max-age=600

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

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

    當然,不同的資源會有不同的 max-age,比如打開 b 站首頁你會看到不同資源的 max-age 是不同的:

    圖片

    比如一些庫的 js 文件就設置了 31536000,也就是 1 年后過期,因為一般也不會變,以年為單位沒啥問題。

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

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

    沒錯,這也是 HTTP 1.1 做的設計,他們想把緩存相關的 header 都集中到一起,所以就包了一層,都放在 Cache-Control 的 header 里。

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

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

    但是這樣就行了么?

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

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

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

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

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

    圖片

    服務端返回資源的時候就會帶上這倆 header。

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

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

    If-None-Match: “bfc13a64729c4290ef5b2c2730249c88ca92d82d”

    帶上 last-modified 時間的叫做 If-Modified-Since:

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

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

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

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

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

    Cache-control: immutable

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

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

    代理服務器的緩存怎么控制?

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

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

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

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

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

    Cache-control: private, max-age=31536000

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

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

    Cache-control: max-stale=600

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

    Cache-control: stale-while-revalidate=600

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

    Cache-control: stale-if-error=600

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

    所以說,max-age 的過期時間也不是完全強制的,是可以允許過期后用一段時間的。

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

    用這個指令 must-revalidate:

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

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

    可能有的同學會有疑問,緩存不都是自己設置的么,咋還一個允許過期,一個禁止過期呢?

    自己會同時用這兩種和自己玩么?

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

    最后,HTTP 當然也支持禁止緩存,也就是這樣:

    Cache-control: no-store

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

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

    Cache-control: no-cache

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

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

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

    總結(jié)

    緩存能加快也面的打開速度,也能減輕服務器壓力,所以 HTTP 設計了緩存機制。

    HTTP 1.0 的時候是使用 Expires 的 header 來控制的,指定一個 GMT 的過期時間,但是當瀏覽器時間不準的時候就有問題了。

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

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

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

    public:允許代理服務器緩存資源

    s-maxage:代理服務器的資源過期時間

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

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

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

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

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

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

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

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

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

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

    相關推薦

    • 短視頻策劃內(nèi)容的3個要點(短視頻策劃內(nèi)容怎么做)

      短視頻在制作時,內(nèi)容框架非常重要。如果直奔主題,然后結(jié)束,聚卓告訴你,這樣的短視頻已經(jīng)過時了?,F(xiàn)在的短視頻需要框架的,但不是任何框架,它需要一種易于理解和消化的框架。而且,現(xiàn)在大多…

      2022年11月27日
    • 推薦48個微商引流推廣的方法(微商引流推廣的方法有哪些)

      微商引流技能01——同行互推 資源共享,大家才會共贏。加入你是做穴位貼的,你的朋友是做化妝品的,這是兩個沒有交集的行業(yè),你們可以友情互推,這樣每個月的資源就都擴大了一倍,而且這些資…

      2022年11月27日
    • 非匿名指令新手十連怎么選?非匿名指令新手無限十連選擇推薦

      非匿名指令新手十連怎么選?進入游戲之后大家能得到一個新手無限十連,可以幫大家抽到滿意的角色,新手十連的選擇小編在下面也會有分享,不知道如何選擇的可以看看小編提供的攻略,了解新手十連…

      2022年11月25日
    • 5+3疫情防控從哪天開始算(遼寧疫情防控最新政策)

      最近有關國內(nèi)各地的疫情大家也都有在持續(xù)關注,目前國內(nèi)各地疫情隔離時間也根據(jù)二十條防控措施有了新的調(diào)整。那么,5+3疫情防控從哪天開始算?對于密接的5+3隔離時間計算大家還是比較關心…

      2022年11月25日
    • 藍碼怎么變綠碼需要幾天(藍碼怎么變綠碼需要幾天)

      大家都知道健康碼的顏色有紅碼、綠碼、黃碼,近日湖南健康碼上線“藍碼”,不少小伙伴發(fā)現(xiàn)自己健康碼變藍了,都想趕緊恢復綠碼,那么藍碼怎么變綠碼需要幾天?下面小編為大家?guī)硭{碼變綠碼需要…

      2022年11月25日
    • 拼多多百億補貼預售一般多久發(fā)貨(拼多多百億補貼預售)

      拼多多里面有很多優(yōu)惠活動,其中百億補貼活動非?;鸨?,一些里面的東西價格比別的平臺便宜,質(zhì)量也有保障,還有預售的活動,那么拼多多百億補貼預售一般多久發(fā)貨?下面小編為大家?guī)砥炊喽喟賰|…

      2022年11月25日
    • 北京疫情多久能解除封控(北京疫情還要多久結(jié)束)

      最近一段時間北京疫情形勢備受關注,馬上就要到年底了,不少人想要去北京辦事,。都非常關注當?shù)匾咔橄嚓P政策,那么 北京疫情多久能解除封控?北京疫情什么時候恢復正常生活?下面小編為大家?guī)А?/p>

      2022年11月25日
    • 小紅書平臺的一些機制及玩法詳解(小紅書玩法有哪些)

      關于小紅書 一:小紅書平臺的一些機制 1. 筆記內(nèi)容的CES評分機制 2. 筆記流量入口與長尾效應 二:小紅書優(yōu)質(zhì)筆記的特點(分維度、類型分析) 1.筆記的本身架構組成 維度 2.…

      2022年11月25日
    • 博客營銷的3大優(yōu)勢解析(博客營銷怎么做)

      不知不覺已經(jīng)寫了24篇文章,加上這篇是第25篇了,都是自己這幾年來用過的營銷方法,如果遇到有些不懂的,我會咨詢我的朋友和同事幫忙,盡量讓每一篇有價值,哪怕是對大家有一點點幫助也行,…

      2022年11月25日
    • 什么是內(nèi)容營銷策略如何策劃一套成功的內(nèi)容營銷策略

      很多時候,營銷人員會在創(chuàng)作營銷內(nèi)容時感到沮喪,這也是很多企業(yè)至今沒用好數(shù)字化營銷工具的重要原因之一。 舉個例子,您可能會花上數(shù)小時期待制作一些令人驚嘆的東西,實際卻是得到很少的受眾…

      2022年11月25日

    聯(lián)系我們

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