成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

圖說 HTTP 緩存

lx1036 / 787人閱讀

摘要:緩存主要通過首部來控制。表示當前響應數(shù)據(jù)是單個用戶所獨占的,只能被客戶端緩存,不能被代理服務器緩存。其值是任意整數(shù),和負數(shù)表示緩存過期,正數(shù)值加上當前響應頭中的首部值即為過期時間??蛻舳耸盏胶?,直接使用緩存的,同時更新緩存有效期。

無論是軟件應用還是硬件應用,緩存都扮演著重要的角色,其對提升性能的重要性無可置疑。

本文主要介紹 HTTP 緩存,涉及其原理和應用。HTTP 緩存主要通過 HTTP 首部來控制。

緩存示例

先看一個簡單的緩存示例:

瀏覽器首次請求 app.js 時,服務器會返回資源內容和相關頭部,其中 Cache-Control: max-age=120 告訴瀏覽器說,這個資源的緩存有效期為 120 秒,從當前時間 Date: Mon, 05 Mar 2018 08:00:00 GMT 開始算起。瀏覽器收到資源后便將 app.js 及其相應頭部存儲在本地。

如果在 05 Mar, 2018 08:02:00 GMT 之前再次請求 app.js ,則瀏覽器會直接使用存儲在本地的資源,而不用再次向服務器發(fā)起請求。

這個過程中,我們就說 app.js緩存且命中了。

基本概念

在進一步理解緩存之前,先看下跟緩存相關的幾個概念:

命中:請求數(shù)據(jù)不需再次下載,可以直接使用緩存數(shù)據(jù)

過期:緩存數(shù)據(jù)超過設置的有效時間,將被標記為“陳舊”

驗證:判斷過期緩存是否仍然有效,需要與服務器交互

失效:緩存數(shù)據(jù)不再有效,需要從服務端重新下載新數(shù)據(jù)

基本理解

HTTP 緩存涉及到請求-響應鏈上的多個角色,包括客戶端(本文指瀏覽器)、代理和服務器。
其中,瀏覽器自身也實現(xiàn)了緩存功能。瀏覽器在請求資源時,總是先從本地緩存中查找,如果找到未過期資源,則直接使用,否則向服務器發(fā)起請求。
代理也是服務器的一種,但一般情況下不會把它多帶帶抽出來分析,只有在跟它有關的地方會把它區(qū)分于源服務器。所以,下文的示例圖中將不會把它列進去。

HTTP 緩存的理解基本上可以總結為三個問題:

緩存數(shù)據(jù)可以存儲在哪些設備上?(WHERE)

緩存數(shù)據(jù)如何判斷過期?(HOW)

過期緩存內容是否真的需要重新下載?(WHETHER)

問題 1 說明存儲緩存數(shù)據(jù)的設備是多樣的,可以存儲于各級代理服務器,也可以存儲于瀏覽器本地。

問題 2 說明使用什么辦法來判斷緩存數(shù)據(jù)是否已經(jīng)過期,當然是比較時間啦,那么如何比較呢?

問題 3 說明緩存雖然過期了,但是其內容仍然可能與服務端一致,這時就沒必要重新下載相同數(shù)據(jù),只需要向服務端詢問下是否可以繼續(xù)使用緩存即可。

帶著上面三個問題去理解 HTTP 緩存頭部設置會更有助于理解和記憶。

有人根據(jù)是否需要進行問題 3 中的重新驗證把緩存策略的設置分為強緩存和協(xié)商緩存,強緩存無須再次驗證的緩存策略,協(xié)商緩存是需要再次驗證的緩存策略。
兩者的區(qū)別在于,協(xié)商緩存多發(fā)起了一次 HTTP 請求。

緩存首部

HTTP 緩存主要通過 HTTP 首部來實現(xiàn)緩存控制。這些與緩存相關的 HTTP 首部這里統(tǒng)稱為緩存首部,具體首部如下表所示。

首部字段 首次定義 首部類型
Pragma HTTP/1.0 通用首部
Age HTTP/1.1 響應首部
Expires HTTP/1.0 實體首部
Cache-Control HTTP/1.1 通用首部
Etag HTTP/1.1 響應首部
If-Match HTTP/1.1 請求首部
If-None-Match HTTP/1.1 請求首部
If-Modified-Since HTTP/1.0 請求首部
Last-Modified HTTP/1.0 實體首部

其中,“首次定義”是指首次出現(xiàn)在哪個 HTTP 版本。之所以列出這項內容,是因為實際應用需要考慮兼容舊版 HTTP

現(xiàn)代的 HTTP 緩存策略主要使用 Cache-Control 實現(xiàn),它是目前最新的緩存首部,用于取代較老的緩存首部如 Pragma 、Expires 等。所以應用中應該傾向于使用 Cache-Control 。但是為了支持只實現(xiàn)了 HTTP/1.0 的客戶端設備,服務端通常還是都會同時設置 ExpiresPragmaCache-Control 等,此時 Cache-Control 會有更高的優(yōu)先級。提醒一下,現(xiàn)代瀏覽器都已支持 Cache-Control 。

Cache-Control

Cache-Control通用首部,這意味著它既可以出現(xiàn)在請求中,也可以出現(xiàn)在響應中。

Cache-Control 的值可由多個字段組合而成,以逗號分隔,如 Cache-Control: private,max-age=3600 。下面對常用的可取字段進行說明。

public: 表示當前響應數(shù)據(jù)所有用戶共享的,可以被任何設備緩存,包括客戶端、代理服務器等。

private: 表示當前響應數(shù)據(jù)是單個用戶所獨占的,只能被客戶端緩存,不能被代理服務器緩存。

max-age=: 指定緩存的有效時間,單位為秒。其值是任意整數(shù),0 和負數(shù)表示緩存過期,正數(shù)值加上當前響應頭中的 Date 首部值即為過期時間。

max-stale[=]: 只用于請求,表示客戶端仍然愿意接受過期緩存,只要過期時間沒超過指定時間,如果未指定時間,則表示任何過期的時間。

min-fresh=: 只用于請求,表示客戶端愿意接受還剩余多少秒過期的緩存。

s-maxage=: 功能與 max-age 一致,但它僅作用于共享緩存,對私有緩存無效。

no-cache: 并非字面意思,它并非禁止緩存,而是強制在使用已緩存數(shù)據(jù)之前,需要去服務端驗證一下是否可以使用緩存數(shù)據(jù)。

no-store: 真正的禁止緩存,任何設備都不允許緩存,每次請求都需要向服務端重新獲取數(shù)據(jù)。

no-transform: 表示響應的實體數(shù)據(jù)不應被轉換。Content-Encoding 、Content-RangeContent-Type 首部也不能被修改。實際應用中,有些代理服務器會對圖片資源進行格式轉換以節(jié)省空間或者帶寬。

作為通用首部,其部分指令值可以出現(xiàn)在請求首部,也可以出現(xiàn)在響應首部,兩者可能略有區(qū)別:

指令值 請求 響應
public - 可共享數(shù)據(jù),可被任何設備緩存
private - 用戶私有數(shù)據(jù),只能被客戶端緩存
no-cache 使用前需驗證 使用前需驗證
no-store 禁止使用緩存數(shù)據(jù) 禁止緩存
max-age 要求資源的 age 小于這個時間 最大過期時間
min-fresh 要求資源至少還剩余多少過期時間 -
max-stale 超過過期時間多少秒內仍愿意接受 -
no-transform 不要轉換格式 不要轉換格式

這些指令用在請求首部的情況比較少見,最可能接觸的地方是 Chrome DevTools 中的 Network 標簽頁。
其中,有個 Disable cache 選項,選中后 DevTools 會自動給所有請求頭部加上 Cache-Control: no-cache 首部,以告訴瀏覽器和代理使用本地緩存之前必須先驗證。

Last-Modified/If-Modified-Since

If-Modified-Since 首部比較的是資源的修改時間,精度為秒,是一種緩存過期后的常用驗證方式。一般來說,驗證資源是否修改過,對比資源的修改時間是一種最簡單的辦法。

使用過程如下:

客戶端首次請求 app.js 時,服務器響應帶上 Last-Modified 首部,告訴客戶端當前資源的最后修改時間??蛻舳烁鶕?jù) Cache-Control: max-age=120 ,把 app.js 和響應首部緩存起來。

客戶端再次發(fā)起請求 app.js 時,把之前保存的 Last-Modified 時間放入 If-Modified-Since 首部發(fā)給服務器。服務器發(fā)現(xiàn)資源的 Last-Modified 時間沒有發(fā)生改變,于是直接響應 304 ??蛻舳耸盏?304 后,直接使用緩存的 app.js ,同時更新緩存有效期。

客戶端再次發(fā)起請求 app.js 時,把之前保存的 Last-Modified 時間放入 If-Modified-Since 首部發(fā)給服務器。服務器發(fā)現(xiàn)資源的 Last-Modified 時間已經(jīng)發(fā)生改變,于是響應 200 ,將修改后的 app.js 和新的 Last-Modified 發(fā)送給客戶端。客戶端收到 200 后,重新下載新的 app.js ,并把新的 app.js 和響應首部緩存起來,替換原先的舊緩存。

ETag/If-Matched/If-None-Match

ETag 叫實體標簽(Entity Tag),用于表示實體資源是否發(fā)生變化,其生成原理類似 MD5 ,也是一種用于驗證的首部。當響應的首部信息或者消息實體發(fā)生變化時,實體標簽也會改變。

使用過程如下:

客戶端首次請求 app.js 時,服務器響應帶上 ETag 首部,告訴客戶端當前資源的實體標簽。客戶端根據(jù) Cache-Control: max-age=120 ,把 app.js 和響應首部緩存起來。

客戶端再次發(fā)起請求 app.js 時,把之前保存的 ETag 值放入 If-None-Match 首部發(fā)給服務器。服務器發(fā)現(xiàn)自己的資源 ETag 值并沒有發(fā)生改變,于是直接響應 304 ??蛻舳耸盏?304 后,直接使用緩存的 app.js ,同時更新緩存有效期。

客戶端再次發(fā)起請求 app.js 時,把之前保存的 ETag 值放入 If-None-Match 首部發(fā)給服務器。服務器發(fā)現(xiàn)自己的資源 ETag已經(jīng)發(fā)生改變,于是響應 200 ,將修改后的 app.js 和新的 ETag 發(fā)送給客戶端。客戶端收到 200 后,重新下載新的 app.js ,并把新的 app.js 和響應首部緩存起來,替換原先的舊緩存。

當客戶端本地存儲有多個版本的資源時,會把所有的實體標簽都上傳,形如 ETag: "abc","def" ,服務端會使用 ETag 首部返回匹配中的實體標簽值。

實體標簽分為強標簽(Strong ETag)和弱標簽(Weak ETag),弱標簽以 W/ 開頭,如 ETag: W/"1234" 。強標簽使用強比較,弱標簽使用弱比較。強比較意味著兩個比較對象的每一個字節(jié)都相同,弱比較意味著兩者語義相同(Semantic Equivalence)。舉個栗子,假如響應首部包含一個渲染時間 Rendered-Time,A 響應的渲染時間為 365,B 響應的渲染時間為 345,兩個響應的實體內容一致。這種情況下,我們可以說 A 和 B 弱比較相等,強比較不相等。

一般來說,靜態(tài)內容使用強標簽,動態(tài)生成的內容使用弱標簽。

由此可以看出,實體首部可以解決一些 Last-Modified 無法解決的問題:

某些服務器不能得到文件的精確的最后修改時間

修改時間變了并不意味著內容的改變,比如改完保存后又改回去

修改時間只能精確到秒,一秒內的修改無法判斷

If-MatchETag 的另一種用法:避免“空中碰撞”,以防編輯沖突。當客戶端使用 PUT 或者 POST 更新服務端資源時,需要使用 If-Match 來攜帶實體標簽給服務端,以確??蛻舳艘薷牡馁Y源沒有被別人修改過,避免覆蓋別人的修改。不過這種用法比較少,可以不用深究。

Expires

Expires 指明資源的過期時間,如 Expires: Wed, 04 Jul 2012 08:26:05 GMT 。非法的日期格式(如 0)將會被當做過去的時間,表示該資源已經(jīng)過期。

如果 ExpiresCache-Controlmax-age 或者 s-maxage 同時出現(xiàn),Expires 將被忽略。

Age

Age 表示資源在代理服務器上已經(jīng)緩存了多久時間,單位為秒。如果是 Age: 0 ,表明該資源剛剛從服務器獲取。它的計算方式一般使用代理服務器當前的時間減去緩存資源的 Date 時間。

Pragma

Pragma 是 HTTP/1.0 中引入的首部,現(xiàn)在使用時一般用于向后兼容 HTTP/1.0,不鼓勵使用。

Pragma: no-cache 的作用與 Cache-Control: no-cache 一致,表示需要跟服務器進行驗證后才能使用緩存資源。

啟發(fā)式緩存策略

并不是每個服務器都會返回明確的緩存策略,這種情況下客戶端會采取啟發(fā)式緩存策略。注意,只有在服務端沒有返回明確的緩存策略時才會激活啟發(fā)式緩存策略。

啟發(fā)式緩存策略會根據(jù)其他的首部信息來計算一個過期時間,其他的首部通常是 DateLast-Modified 。此時,緩存有效期一般取兩者差值的 10% 。

使用啟發(fā)式緩存策略時,如果超過當前時間 24 小時且從未警告過,瀏覽器或者代理服務器應該在響應中產(chǎn)生一個警告首部字段 Warning: 113 。

參考資料

HTTP/1.0, RFC1945

HTTP/1.1, RFC2616

HTTP/1.1 Caching, RFC7323

HTTP 緩存, Google Developers

The-difference-between-strong-and-weak-ETags

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/61963.html

相關文章

  • 圖說 Firefox 全新 CSS 引擎

    摘要:的主要組件包含了一個全新的引擎,稱為量子,也稱為。這個新引擎集成了四種不同瀏覽器的最新創(chuàng)新技術,創(chuàng)造出一個全新的超級引擎。這可以發(fā)生在多個圖層上。最終,擁有最高特異性的規(guī)則會勝出。 原文:Inside a Super Fast CSS Engine: Quantum CSS(Aka Stylo), Lin Clark 注:原文發(fā)布于 2017 年 8 月,本文翻譯于 2018 年 4 ...

    lsxiao 評論0 收藏0
  • 圖說 WebAssembly(一):序言

    摘要:性能簡史在年,被創(chuàng)造出來時并不是沖著性能去的。而且在之后的十年發(fā)展中,它的性能一直是很低的。的引入成就了性能提升的一個轉折點,其執(zhí)行速度比以往快了之多。性能提升也使得在全新的問題上使用成為可能。現(xiàn)在,極可能是下一個性能轉折點。 你可能已經(jīng)聽說 WebAssembly 代碼跑起來非??臁5悄阒肋@是為什么嗎?在本系列文章中,我們將探究其原因。 何為 WebAssembly WebAss...

    codergarden 評論0 收藏0
  • DeepMind 推出貝葉斯 RNN,語言建模和圖說生成超越傳統(tǒng) RNN

    摘要:我們還經(jīng)驗性地演示了貝葉斯在語言建模基準和生成圖說任務上優(yōu)于傳統(tǒng),以及通過使用不同的訓練方案,這些方法如何改進我們的模型。第節(jié)和第節(jié)分別回顧了通過反向傳播做貝葉斯,和通過時間做反向傳播。 摘要在這項工作里,我們探討了一種用于 RNN 的簡單變分貝葉斯方案(straightforward variational Bayes scheme)。首先,我們表明了一個通過時間截斷反向傳播的簡單變化,能...

    KunMinX 評論0 收藏0
  • 圖說 WebAssembly(三):什么是匯編

    摘要:為了更好的理解,我們有必要去先理解什么是匯編,以及編譯器是如何產(chǎn)生匯編的。什么是匯編現(xiàn)在,我們來看看外星人的大腦是如何工作的。這些注釋就是匯編,也稱為符號機器碼。結束以上的內容就是什么是匯編以及它是如何從高級編程語言翻譯過來的。 本文是圖說 WebAssembly 系列文章的第三篇。如果您還未閱讀之前的文章,建議您從第一篇入手。 為了更好的理解 WebAssembly ,我們有必要去先...

    劉福 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<