日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
掌握HTTP緩存——從請(qǐng)求到響應(yīng)過(guò)程的一切(下)

CDN類(lèi)的網(wǎng)站曾經(jīng)一度雄踞 Alexa 域名排行的前 100。以前一些小網(wǎng)站不需要使用 CDN 或者根本負(fù)擔(dān)不起其價(jià)格,不過(guò)這一現(xiàn)象近幾年發(fā)生了很大的變化,CDN 市場(chǎng)上出現(xiàn)了很多按次付費(fèi),非公司性的提供商,這使得 CDN 變成人人都能負(fù)擔(dān)的起的一種服務(wù)了。本文講述的就是如何使用這種簡(jiǎn)單易用的緩存服務(wù)。

創(chuàng)新互聯(lián)建站主營(yíng)太湖網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,app開(kāi)發(fā)定制,太湖h5微信小程序開(kāi)發(fā)搭建,太湖網(wǎng)站營(yíng)銷(xiāo)推廣歡迎太湖等地區(qū)企業(yè)咨詢(xún)

上篇文章掌握 HTTP 緩存--從請(qǐng)求到響應(yīng)過(guò)程的一切(上) 中,我們討論了關(guān)于利用 HTTP 頭來(lái)解決緩存問(wèn)題,這篇文章我們將介紹緩存和 Cookie之間的關(guān)系。

Cookies

你已經(jīng)知道了緩存頭是如何起作用的,現(xiàn)在我們來(lái)看下在緩存里面 cookie 起了什么作用。首先, Cookie 的設(shè)定也在 HTTP 響應(yīng)頭中,名字是 Set-Cookie。設(shè)置一個(gè) cookie 的目的是標(biāo)識(shí)這個(gè)用戶,就是說(shuō)你需要為每個(gè)用戶設(shè)置一個(gè) cookie。

想象一下緩存的場(chǎng)景,你是否會(huì)緩存一個(gè)包含了Set-Cookie的 HTTP 響應(yīng),在緩存時(shí)間內(nèi),每個(gè)人都會(huì)得到相同的 cookie 和同樣的用戶 session?你肯定不想這樣。

另外,用戶 session 狀態(tài)的改變可能會(huì)影響到響應(yīng)內(nèi)容的變化。一個(gè)簡(jiǎn)單的場(chǎng)景:電商購(gòu)物車(chē)。你給用戶要么提供一個(gè)空購(gòu)物車(chē),要么是用戶自己選了很多物品的購(gòu)物車(chē)。同樣的道理,你不希望這個(gè)也被緩存,畢竟每個(gè)用戶都應(yīng)該有自己的購(gòu)物車(chē)。

一個(gè)解決方法是在運(yùn)行時(shí)通過(guò) JavaScript 設(shè)置 Cookie,比如 Google Analytics。GA 通過(guò) JS 設(shè)置 cookie,但這個(gè) cookie 既不影響渲染,也不設(shè)置 Set-Cookie 頭。GA 會(huì)在目標(biāo)網(wǎng)站上添加類(lèi)似于 "you are tracked via Google Analytics" 的圖標(biāo),但是只要這些改變都是在運(yùn)行時(shí)添加進(jìn)去的,就都沒(méi)有問(wèn)題。

正確處理 cookie 和緩存

首先你需要知道你網(wǎng)站的 cookie 的工作原理。cookie 是不是只在特定時(shí)間使用(如在用戶登錄過(guò)程中使用)?原則上,cookie 是不是會(huì)被注入到所有響應(yīng)?

正如上一節(jié)所說(shuō)的,不論何時(shí)服務(wù)器返回了一個(gè)帶有Set-Cookie 的響應(yīng),你都希望能夠保證它不會(huì)被緩存。那么問(wèn)題就轉(zhuǎn)化成為,當(dāng)你返回一個(gè)帶有“用戶特性”內(nèi)容的響應(yīng)時(shí)(如購(gòu)物車(chē)),CDN /代理服務(wù)器,會(huì)作何操作?

  • 如果沒(méi)設(shè)置 Set-Cookie,是不是允許緩存呢?
  • 如果設(shè)置了 Set-Cookie,是不是自動(dòng)丟棄所有Cache-Control 頭呢?

其實(shí),如果從應(yīng)用層面來(lái)講,你盡管可以去實(shí)現(xiàn)你所喜歡的 web 應(yīng)用就可以了,至于 cookie 和 CDN 都是自動(dòng)設(shè)置的。還是用 Apache 的 .htaccess 來(lái)作為例子來(lái)解釋?zhuān)?/p>

 
 
 
  1. # 1) 如果 cookie 沒(méi)設(shè)置,允許緩存 
  2. Header set Cache-Control "public max-age=3600" "expr=-z resp('Set-Cookie') 
  3.  
  4. # 2) 如果 cookie 被設(shè)置,不允許緩存 
  5. Header always remove Cache-Control "expr=-n resp('Set-Cookie') 
  6.  
  7. # 2a) 第二條的另一種形式,如果設(shè)置了 cookie,緩存時(shí)間設(shè)置成0 
  8. Header set Cache-Control "no-cache max-age=0 must-revalidate" "expr=-n resp('Set-Cookie') 
  • 規(guī)則1:如果沒(méi)設(shè)置 Set-Cookie,則給Cache-Control 設(shè)置一個(gè)默認(rèn)值;
  • 規(guī)則2:如果設(shè)置了 Set-Cookie,則忽略Cache-Control;
  • 規(guī)則2a:是規(guī)則2的另一種表示形式,設(shè)置最大緩存時(shí)間是 0。

無(wú) cookie 的訪問(wèn)路徑

一些 CMS / 框架還在使用一種暴力的方式種 cookie。而實(shí)際上,決定是否種 cookie 取決于不同的因素,比如會(huì)話時(shí)間因素。如果你有一個(gè)很高安全性的 web 應(yīng)用,設(shè)置會(huì)話時(shí)間是 5 分鐘,那么為每個(gè)響應(yīng)設(shè)置一個(gè)新 cookie 都不過(guò)分。而假設(shè)你的應(yīng)用連“用戶特性”都沒(méi)有,也就是說(shuō)所有的東西對(duì)所有用戶都是公用的,那么設(shè)置任何形式的 cookie 都是沒(méi)有道理的。

所以下面這個(gè)例子是否適合你自己,很大程度上依賴(lài)于你的應(yīng)用到底是什么類(lèi)型的。我們來(lái)一起看一下,我先給一下這個(gè)例子的上下文關(guān)系:假設(shè)你有個(gè)新網(wǎng)站,你的所有文章都在http://www.foobar.tld/news/item/ 這個(gè)路徑下面?,F(xiàn)在你希望能夠保證,所有訪問(wèn) /news/item/ 的路徑都不包含 Set-Cookie,因?yàn)槟愦_定不需要 cookie。

 
 
 
  1. # 通用 PHP 重定向做法,將"?path=$1"寫(xiě)到重定向規(guī)則里 
  2. RewriteCond %{REQUEST_FILENAME} !-d 
  3. RewriteCond %{REQUEST_FILENAME} !-f 
  4. RewriteRule ^(.*)$ index.php?path=$1 [NC,L,QSA] 
  5. RewriteRule ^$ index.php [NC,L,QSA] 
  6.  
  7. # 利用 query 中的 path= 來(lái)判斷 
  8.  
  9.     Header always unset Set-Cookie 
  10.  

 

通過(guò)這樣的設(shè)置,你就可以保證所有訪問(wèn)/news/item/ 的路徑都不包含 Set-Cookie。而到底是否應(yīng)該設(shè)置 cookie,需要你根據(jù)你自己的應(yīng)用特點(diǎn)來(lái)判斷。

設(shè)計(jì)出來(lái)的緩存能力

有很多設(shè)計(jì)方案可以使你的 web 應(yīng)用具有高緩存性。鑒于本文僅僅是一篇文章而不是一本書(shū),我不可能每個(gè)點(diǎn)都深入的來(lái)講,但是我可以著重提一下通用的方法。

我還用電商作為例子。假設(shè)電商網(wǎng)站首頁(yè)的 top 位置上展示了正在出售的物品,生成這些物品需要進(jìn)行若干次的數(shù)據(jù)庫(kù)操作,代價(jià)比較大,因此希望把它們緩存起來(lái)。但是,問(wèn)題在于購(gòu)物車(chē),它是為那些登陸用戶準(zhǔn)備的,所以希望得到的結(jié)果是: top 物品是一樣的,而針對(duì)登陸用戶展示購(gòu)物車(chē)。

那么優(yōu)化策略首先要為每個(gè)用戶提供一個(gè)和登陸狀態(tài)無(wú)關(guān)的“通用”頁(yè)。然后通過(guò) JavaScript 為已經(jīng)生成的網(wǎng)頁(yè)提供購(gòu)物車(chē)。站在用戶的視角,最終展示形式是一樣的。那么現(xiàn)在你有了兩個(gè)請(qǐng)求(整個(gè)網(wǎng)頁(yè)請(qǐng)求 + 購(gòu)物車(chē)請(qǐng)求),而不是一個(gè)請(qǐng)求(整個(gè)網(wǎng)頁(yè)請(qǐng)求,包含購(gòu)物車(chē))。ok,現(xiàn)在你可以把代價(jià)很大的部分,即 top 物品分離出來(lái),把它們緩存起來(lái)了。

這種方法或者其延伸方法,不適合已經(jīng)開(kāi)發(fā)好的項(xiàng)目。因?yàn)樗赡軙?huì)改變很多接口和視圖層(MVC 架構(gòu))的內(nèi)容。最好你在一開(kāi)始就設(shè)計(jì)好。

緩存失效:busting 和 purging

使用 max-age 和 s-maxage 你已經(jīng)可以很好地控制一個(gè)指定的響應(yīng)被緩存多長(zhǎng)時(shí)間。但是這不足以適用于所有的情況。這些設(shè)置都是在返回響應(yīng)時(shí)預(yù)設(shè)的,而現(xiàn)實(shí)情況往往是并不知道一個(gè)響應(yīng)應(yīng)該設(shè)置多久期滿?;叵胍幌聞偛烹娚淌醉?yè)的例子:假設(shè)它包含了展示在 top 位置的 10 個(gè)實(shí)體。你設(shè)置了 max-age=900給這個(gè)首頁(yè)以保證每15分鐘刷新一次?,F(xiàn)在,其中 1 個(gè)實(shí)體由于發(fā)布了太久了要被撤銷(xiāo),那么你就需要把之前的緩存響應(yīng)刪掉,這時(shí)候其實(shí)還沒(méi)到 15 分鐘,那么該怎么辦?

不要擔(dān)心,這是一個(gè)常見(jiàn)的問(wèn)題,有很多方法解決。首先我們先來(lái)解釋一下術(shù)語(yǔ):

  • 緩存 busting,是用來(lái)解決瀏覽器長(zhǎng)期緩存問(wèn)題,它通過(guò)版本標(biāo)識(shí)來(lái)告訴瀏覽器該文件有一個(gè)新的版本。這時(shí)瀏覽器將不會(huì)從本地緩存取內(nèi)容,而從源服務(wù)器請(qǐng)求新版本的文件。緩存 busting的詳細(xì)介紹在這里:What is Cache Busting?。
  • 緩存 purging,表示直接從緩存中刪除內(nèi)容(即響應(yīng)),以使得緩存可以立馬得到更新。

用于版本管理的緩存 busting

這種方法經(jīng)常使用在 CSS 文件、JS 文件上。通常一個(gè)確切的版本號(hào)、一串哈?;蛘邥r(shí)間戳都可以用作標(biāo)識(shí),如下面的例子:

  • 數(shù)字版本號(hào):style-v1.css,style.css?v=1
  • 哈希串版本:style.css?d3b07384d113edec49eaa6238ad5ff00
  • 時(shí)間戳版本:styles.css?t=1486398121

這時(shí)候在發(fā)布程序的時(shí)候,你只要注意文件的版本就可以了。舉個(gè)例子,一個(gè) HTML 網(wǎng)頁(yè)通過(guò) 這種形式包含了一個(gè) CSS 文件。CSS 文件將會(huì)被緩存起來(lái),這時(shí)如果你想讓你的新 CSS 文件起作用,那么用最新的版本號(hào)命名它就可以。如果不做任何變化的話,即便你更新了文件,這個(gè) HTML 還會(huì)使用緩存中的舊 CSS 文件。

緩存 purging

不同 CDN 供應(yīng)商清除緩存的方式不一樣。很多供應(yīng)商都是基于開(kāi)源軟件 Varnish 來(lái)構(gòu)建自己的 CDN 服務(wù),所以一個(gè)通用的做法是在 HTPP 請(qǐng)求中使用 PURGE 結(jié)構(gòu),如:

 
 
 
  1. PURGE /news/item/i-am-obsolete HTTP/1.1 
  2. Host: www.foobar.tld 

使用這個(gè)請(qǐng)求通常需要權(quán)限認(rèn)證,或者是源確認(rèn)(即 IP 白名單),不過(guò)不同供應(yīng)商的要求也不一樣。

清除一個(gè)或幾個(gè)緩存項(xiàng)比較容易,但是在某些場(chǎng)景下,卻不是這么簡(jiǎn)單。舉個(gè)例子,一個(gè)博客的場(chǎng)景,博客里面都有關(guān)于作者的部分,現(xiàn)在你要改變關(guān)于作者的一些內(nèi)容,那么你需要手動(dòng)清理所有包含了作者信息的頁(yè)面。你確實(shí)可以一個(gè)一個(gè)手動(dòng)清理,但是假設(shè)你有成千上萬(wàn)個(gè)網(wǎng)頁(yè)被影響了,那問(wèn)題就變得麻煩了。

下面介紹一個(gè)解決方案。

代理標(biāo)簽

“代理標(biāo)簽” 這個(gè)名字來(lái)源于 CDN 供應(yīng)商 Fastly,不同供應(yīng)商給它起的名字不一樣,比如還有叫它“緩存標(biāo)簽”的,Varnish 叫它 Hashtwo/Xkey,這里我就不詳細(xì)介紹其他供應(yīng)商的情況了。

不論它叫什么,它們的目的都是一樣的:給響應(yīng)打標(biāo)簽。這樣你就可以輕松地從緩存中刪除相關(guān)的標(biāo)簽就可以,甚至都不用知道緩存的到底是什么東西。

還是拿<客戶端-代理-源端>來(lái)舉例子,源端返回一個(gè)含有代理標(biāo)簽的響應(yīng):

 
 
 
  1. HTTP/1.1 200 OK 
  2. Content-Type: text/html 
  3. Content-Length: 123 
  4. Surrogate-Key: top-10 company-acme category-foodstuff 

這個(gè)例子中的標(biāo)簽為:top-10, company-acme,和category-foodstuff。這里給一個(gè)電商的實(shí)際場(chǎng)景來(lái)理解其含義:這個(gè)響應(yīng)包含了電商首頁(yè)的前 10 個(gè)物品,這些物品由 ACME 公司提供,并且其目錄類(lèi)別都設(shè)定為食品類(lèi)。

設(shè)置了標(biāo)簽以后,當(dāng)物品發(fā)生了變化以后,你只需要?jiǎng)h除包含有 company-acme 和 top-10 的標(biāo)簽就可以了。是不是很簡(jiǎn)單?

同樣,具體如何清除緩存的操作方法,不同 CDN 供應(yīng)商是不一樣的。

點(diǎn)擊《掌握 HTTP 緩存——從請(qǐng)求到響應(yīng)過(guò)程的一切(下)》閱讀原文。

【本文是專(zhuān)欄作者“胡子大哈”的原創(chuàng)文章,轉(zhuǎn)載請(qǐng)聯(lián)系作者本人獲取授權(quán)】


網(wǎng)頁(yè)名稱(chēng):掌握HTTP緩存——從請(qǐng)求到響應(yīng)過(guò)程的一切(下)
鏈接地址:http://www.5511xx.com/article/codpooo.html