国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

30 分鐘 HTTP 查漏補(bǔ)缺之 Vary

xiangchaobin / 1328人閱讀

摘要:所以我們要時刻留意,在使用時,一定要根據(jù)緩存命中率作出調(diào)整,在不發(fā)生緩存錯亂的情況之下,盡可能的提高資源的緩存命中率。

寫在前面

最近抽空參加了幾場大廠的面試,突然發(fā)現(xiàn)一個現(xiàn)象,就是不論面試偏服務(wù)端的職位還是偏客戶端的職位,不論面試的 5 年以上的高級職位,還是 3 年左右的中級職位,面試官開頭所問問題必然是關(guān)于 HTTP 的。

我記得之前找工作的時候,似乎都是先考察一些職位所需技能領(lǐng)域的基礎(chǔ)知識,之后再考察關(guān)于 HTTP 的東西,現(xiàn)在大家都將 HTTP 的問題放到面試的開頭來問,我覺的應(yīng)該是越來越多的招聘者意識到,作為一個 Web 開發(fā)者,HTTP 真的是太重要了,必須要先考察。

回想起來,這幾年我自己對于 HTTP 的學(xué)習(xí)大多是碎片化的,很多東西無法系統(tǒng)地在腦海中組織起來。雖然感覺 HTTP 整體的學(xué)習(xí)難度是比較低的,但是各個知識點交雜在一起又變得很復(fù)雜很難,相信大家都會有同感。同時有些知識點,如果在實際工作中沒有采坑或者刻意深挖的話,很自然地就被忽略了。

由于在之前一次面試中,被狠狠地問了若干關(guān)于 Vary 的問題,所以想抽一些時間整理一下那些比較容易讓人忽略的知識點,算是查漏補(bǔ)缺吧。

內(nèi)容協(xié)商

首先需要了解的是內(nèi)容協(xié)商這個術(shù)語。當(dāng)我們通過某個 URI 來訪問其指向的資源時,HTTP 協(xié)議可以通過內(nèi)容協(xié)商機(jī)制提供資源的不同的展示形式。

如果缺少服務(wù)端開發(fā)經(jīng)驗話,對于這個概念可能會感到陌生,但其實我們在工作中幾乎都會遇到它,比如在調(diào)用接口時,經(jīng)常會用到 Accept: application/json 這個頭部,有時可能會用到 Accept: application/xml,這就是內(nèi)容協(xié)商,前者期望接口返回 json 格式的數(shù)據(jù),而后者期望返回 xml 格式的數(shù)據(jù)。

一般客戶端涉及的常見頭部有以下幾個:

Accept: 聲明客戶端可以處理的資源格式

Accept-Charset: 聲明客戶端可以處理的字符集類型

Accept-Language: 聲明客戶端可以理解的自然語言

Accept-Encoding: 聲明客戶端支持的編碼格式

而服務(wù)端涉及的常見頭部包括:

Content-Type: 指示資源的 MIME 類型

Content-Language: 指示該資源所期望的自然語言

Content-Encoding: 指示資源使用該編碼格式進(jìn)行內(nèi)容轉(zhuǎn)換

仔細(xì)觀察的話,會發(fā)現(xiàn)它們其實存在著一定程度的對應(yīng)關(guān)系。原因也很簡單,既然是協(xié)商,那必然就會和兩個人在進(jìn)行說話一樣,如果兩者之間的對話內(nèi)容沒有關(guān)聯(lián),他們還怎么溝通呢?客戶端和服務(wù)端進(jìn)行溝通同理。

如果想詳細(xì)了解該機(jī)制,可以參考MDN的文檔,很詳細(xì),這里就不多說了。

這里順帶說明一下,對于內(nèi)容協(xié)商機(jī)制中涉及的頭部,從 web 發(fā)展歷史上來看已經(jīng)沒有什么實質(zhì)的用途了,原因如下(有興趣的話可以閱讀這篇wiki):

Accept-Charset: 由于 utf-8 成為主流的字符集類型,所以使用其他字符集類型的服務(wù)可以將其轉(zhuǎn)換為 utf-8 類型

Accept-Language: 大體包含以下幾點

提供多種語言服務(wù)的網(wǎng)站往往是基于某種特定語言構(gòu)建,再提供其他語言支持的,這樣每種語言類型的內(nèi)容在質(zhì)量上層次不齊,而訪問者可能會更傾向于內(nèi)容質(zhì)量更高的那一種語言,而內(nèi)容協(xié)商機(jī)制無法替代用戶的主觀判斷

實踐中,對于切換網(wǎng)站語言的功能,切換方式往往更傾向于主動切換(比如提供一個切換的按鈕)而非自動切換

瀏覽器在用戶不提供語言相關(guān)配置的情況下,很難猜測用戶的自然語言傾向(一般可能會根據(jù)地理定位、ip等因素猜測),打個比方,比如我會經(jīng)常出差去日本,但這不代表我會說日語,同時雖然我掛了加拿大的 vps,但是提供中文內(nèi)容的網(wǎng)站,我還是傾向于看中文

Accept: 與 Accept-Language 類似,同樣因為內(nèi)容的格式會因用戶的主觀意識而不同,還有諸多其他因素制約內(nèi)容協(xié)商機(jī)制,所以最終失敗了。

唯一有些用途的是 Accept-Encoding,但鑒于如今大部分現(xiàn)代瀏覽器都已支持多種壓縮方式(常見的如 gzip、br),因此一定程度上已經(jīng)不需要額外聲明這個頭部了,雖然大部分瀏覽器都會自動發(fā)送這個頭部,但其實這會造成額外 23 字節(jié)的浪費。

Vary 頭部

在理解(或者鞏固)了內(nèi)容協(xié)商的概念后,就可以介紹 Vary 這個頭部了。直接引用 MDN 對于它的描述:

The Vary HTTP response header determines how to match future request headers to decide whether a cached response can be used rather than requesting a fresh one from the origin server.

Vary 是一個HTTP響應(yīng)頭部信息,它決定了對于未來的一個請求頭,應(yīng)該使用一個緩存作為響應(yīng)還是向源服務(wù)器請求一個新的響應(yīng)。

單純靠文檔對于 Vary 的描述來理解它其實是有些困難的,最起碼我會有這種感覺。

這個頭部的語法和其他的 HTTP 頭部類似,如下:

Vary: , , ...

不同的頭部之間使用逗號進(jìn)行分割,同時可以指定 * 為它的值,這樣等價于將資源視為唯一,并不進(jìn)行緩存,但這并不是最佳實踐,因此不建議這么做。

Vary 的工作原理

一句話概括它的工作原理就是,就是它表示某個響應(yīng)因某個響應(yīng)頭部而不同。舉個例子,比如 Vary: Accept 的意思即為,響應(yīng)因請求資源格式頭部而不同,那么通過相同 URI 訪問的資源就可以根據(jù)這個頭上知道其內(nèi)容格式不同。

但我們已經(jīng)知道,對于大部分內(nèi)容協(xié)商機(jī)制中涉及的頭部,已經(jīng)被看作是失敗的,那么 Vary 和這些頭部搭配使用還有什么意義呢?話雖如此,但 Vary 還可以與 HTTP 中其他的頭部來搭配使用,從而滿足很多應(yīng)用場景下的特殊需求,比如動態(tài)服務(wù)、防止緩存錯亂等。

Vary 的應(yīng)用場景

以下簡單羅列一些常用的應(yīng)用場景以及采坑指南。

Vary 與 動態(tài)服務(wù)

關(guān)于動態(tài)服務(wù),最常見的莫過于 Vary: User-Agent。眾所周知,UA 是一段特征字符串,通常包含區(qū)分客戶端類型、操作系統(tǒng)、版本號等信息,隨著移動 web 應(yīng)用變得越流行,一個應(yīng)用網(wǎng)站同時提供桌面和移動兩種版本的應(yīng)用是很常見的事情。通過設(shè)置 Vary: User-Agent 頭部,對于搜索引擎,對于關(guān)鍵字的搜索結(jié)果可以提供更加準(zhǔn)確的應(yīng)用版本,對于客戶端,可以使其從緩存服務(wù)器獲取到相應(yīng)應(yīng)用類型的緩存版本,而不是錯誤地將桌面版緩存?zhèn)鬟f給移動版應(yīng)用。

web 應(yīng)用的性能在加載速度這一指標(biāo)上,很大程度上取決于加載資源的大小,而圖片資源是所占比例最大的一塊。為了減少圖片的大小,除了對常見的圖片格式進(jìn)行壓縮以外,chrome 推出的 WebP 格式也是不錯的選擇。但是這里的問題是,不是所有的瀏覽器都支持 WebP 圖片格式的,所以這里使用 Vary: Accept 來針對瀏覽器的支持情況返回相應(yīng)的緩存副本,支持則返回 WebP 格式,不支持則返回縮略圖或者原圖。

還有其他關(guān)于動態(tài)服務(wù)的場景,比如要針對不同分辨率的屏幕加載不同質(zhì)量的圖片(Client Hints 相關(guān)的頭部)、針對不同用戶身份提供不同的資源(Cookie頭部)等等。

Vary 與 緩存錯亂

有時候我們會發(fā)現(xiàn)響應(yīng)中存在 Vary: Accept-Encoding 頭部信息,我原先按照內(nèi)容協(xié)商機(jī)制中所描述的內(nèi)容來理解,但到后來才發(fā)現(xiàn),其實很大程度上是為了防止緩存錯亂的問題。

設(shè)想一下,如果沒有這個頭部,當(dāng)兩個分別支持 gzip 和 不支持 gzip 的客戶端對同一份資源進(jìn)行獲取時,結(jié)果會變得十分微妙。如果不支持 gzip 的客戶端先訪問,緩存代理會緩存未壓縮的版本,那么當(dāng)支持 gzip 的客戶端再訪問時,由于命中緩存,雖然它支持 gzip 但也只能加載未壓縮的資源。反過來同樣如此,支持 gzip 客戶端先訪問,則緩存代理會緩存壓縮版本,當(dāng)不支持 gzip 的客戶端再訪問時,緩存同樣命中,但是由于它無法對壓縮資源解碼,所以會呈現(xiàn)亂碼。

通過 Vary: Accept-Encoding 我們可以防止這種情況的發(fā)生,因為 Vary 在這里其實是扮演著校驗器的角色,它會進(jìn)一步對命中緩存的資源進(jìn)行再校驗,如果發(fā)現(xiàn)頭部信息不同,則會將緩存資源視為無效,從而將請求繼續(xù)轉(zhuǎn)發(fā)至源服務(wù)器。這對于緩存代理服務(wù)器也有一定的益處,因為可以有有依據(jù)地針對不同的 Accept-Encoding 緩存不同的資源副本。

Vary 與 緩存命中率

Vary 雖然可以防止緩存錯亂,但并不代表可以濫用,盲目的使用會適得其反,比如之前提及的 Vary: *,這樣等價于將每個請求視為唯一,并且不緩存其響應(yīng)資源,除非有意為之,不然沒有人會犧牲緩存帶來的性能提升。

同時對于一些 Header 的值是開放性的,比如之前提及的 User-Agent,如果單純從字面量來匹配的話,眾多桌面瀏覽器的值會因各種因素而不同的,如果僅是簡單地將 UA 作為區(qū)分桌面端和移動端的依據(jù),那么緩存命中率會達(dá)到一個很低的水平。如何解決這個問題呢?可以將這些 UA 頭部的值進(jìn)行標(biāo)準(zhǔn)化,比如可以通過正則匹配所有桌面瀏覽器的 UA 并重新更改為 Desktop,之后再轉(zhuǎn)發(fā)至緩存代理和源服務(wù)器,這樣有利于提高緩存命中率,關(guān)于這部分的內(nèi)容,可以參考這篇文章,其中有很細(xì)致的講解。

所以我們要時刻留意,在使用 Vary 時,一定要根據(jù)緩存命中率作出調(diào)整,在不發(fā)生緩存錯亂的情況之下,盡可能的提高資源的緩存命中率。

Vary 與 CORS

對于跨域的有情況,Vary 也包含一些內(nèi)容。HTTP 協(xié)議規(guī)定,當(dāng)服務(wù)端響應(yīng)包含 Access-Control-Allow-Origin 頭部,且它的值是一個具體的域名而不是通配符 *,那么這時必須要包含 Vary: Origin 這個頭部。

為什么要包含這個頭部,因為請求頭中的 Origin 頭部代表了該請求來源的具體域名信息,那么對于不同域名網(wǎng)站所發(fā)起的請求,會使用僅屬于它本身的緩存。一般而言,我們很少會遇到這種問題,因為一般都將 Access-Control-Allow-Origin 設(shè)置為了 *,至少我自己是這樣的。如果想進(jìn)一步了解 Vary 和 CORS 的內(nèi)容,可以參考這篇文章。

最后

差不多就這么多內(nèi)容了,如有錯誤,還望指正。

參考鏈接

內(nèi)容協(xié)商

Best Practices for Using the Vary Header

IE 與 Vary

CORS

Vary

Response with Vary Header

Understanding Vary Header

Getting the most out of Vary with Fastly

Why not conneg

條件型 CORS 響應(yīng)下因缺失 Vary: Origin 導(dǎo)致的緩存錯亂問題

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/62052.html

相關(guān)文章

  • 查漏補(bǔ)缺 - 收藏集 - 掘金

    摘要:醞釀許久之后,筆者準(zhǔn)備接下來撰寫前端面試題系列文章,內(nèi)容涵蓋瀏覽器框架分鐘搞定常用基礎(chǔ)知識前端掘金基礎(chǔ)智商劃重點在實際開發(fā)中,已經(jīng)非常普及了。 這道題--致敬各位10年阿里的前端開發(fā) - 掘金很巧合,我在認(rèn)識了兩位同是10年工作經(jīng)驗的阿里前端開發(fā)小伙伴,不但要向前輩學(xué)習(xí),我有時候還會選擇另一種方法逗逗他們,拿了網(wǎng)上一道經(jīng)典面試題,可能我連去阿里面試的機(jī)會都沒有,但是我感受到了一次面試1...

    YuboonaZhang 評論0 收藏0
  • HTML查漏補(bǔ)缺

    摘要:規(guī)定了標(biāo)記語言的規(guī)則,這樣瀏覽器才能正確地呈現(xiàn)內(nèi)容不基于,所以不需要引用標(biāo)簽都用來做什么的提供有關(guān)頁面的元信息,常用于定義頁面的說明,關(guān)鍵字,最后修改日期,和其它的元數(shù)據(jù)。這些元數(shù)據(jù)將服務(wù)于瀏覽器如何布局或重載頁面,搜索引擎和其它網(wǎng)絡(luò)服務(wù)。 HTML規(guī)范 HTML規(guī)范文檔 H4時代被規(guī)定為錯誤的行為,在H5時代全都被合理化了,比如標(biāo)簽不區(qū)分大小寫、只有開始標(biāo)簽沒有結(jié)束標(biāo)簽、屬性值不...

    daydream 評論0 收藏0
  • 【面試篇】JS基礎(chǔ)知識查漏補(bǔ)缺

    摘要:因為在頁面加載完成后,引擎維護(hù)著兩個隊列,一個是按頁面順序加載的執(zhí)行隊列,還有一個空閑隊列,使用定時函數(shù)就是將回調(diào)函數(shù)加入到空閑隊列中,故和其他定時器是并發(fā)執(zhí)行的。 1.window.onload和$(document).ready()的區(qū)別: ①執(zhí)行時間:window.onload會在所有元素,包括圖片,引用文件加載完成之后執(zhí)行,而$(document).ready()則會在HTML...

    myeveryheart 評論0 收藏0
  • 前端面試題-瀏覽器/服務(wù)端/網(wǎng)絡(luò)

    摘要:同源策略是什么跨域通信同源兩個文檔同源需滿足協(xié)議相同域名相同端口相同跨域通信進(jìn)行操作通信時如果目標(biāo)與當(dāng)前窗口不滿足同源條件,瀏覽器為了安全會阻止跨域操作。 同源策略是什么? javascript跨域通信 同源:兩個文檔同源需滿足 協(xié)議相同 域名相同 端口相同 跨域通信:js進(jìn)行DOM操作、通信時如果目標(biāo)與當(dāng)前窗口不滿足同源條件,瀏覽器為了安全會阻止跨域操作??缬蛲ㄐ磐ǔS幸韵路椒?...

    jsdt 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<