在前面的一篇文章中,我討論了HTTP和它在這一點(diǎn)上的立場。這是一個(gè)將專門關(guān)于緩存。作為用戶,我們很容易因?yàn)榫彌_視頻,加載幾秒鐘的圖片,由于內(nèi)容正在加載而卡住的網(wǎng)頁而感到沮喪。從一些緩存加載資源比從源服務(wù)器獲取資源要快得多。它減少延遲,加速資源加載,減少服務(wù)器上…
在前面的一篇文章中,我討論了HTTP和它在這一點(diǎn)上的立場。這是一個(gè)將專門關(guān)于緩存。
作為用戶,我們很容易因?yàn)榫彌_視頻,加載幾秒鐘的圖片,由于內(nèi)容正在加載而卡住的網(wǎng)頁而感到沮喪。從一些緩存加載資源比從源服務(wù)器獲取資源要快得多。它減少延遲,加速資源加載,減少服務(wù)器上的負(fù)載,降低帶寬成本等。
什么是Web緩存?它是位于客戶端和服務(wù)器之間的某處,持續(xù)查看請求及其響應(yīng),查找可以緩存的任何響應(yīng)。以便在再次進(jìn)行相同請求時(shí)消耗更少的時(shí)間。
注意,這個(gè)圖像只是給你一個(gè)想法。根據(jù)緩存的類型,實(shí)現(xiàn)緩存的位置可能會(huì)有所不同。更多這一點(diǎn)。
在我們進(jìn)一步詳細(xì)介紹之前,讓我在文章中進(jìn)一步介紹將要使用的術(shù)語
Web緩存可以是共享的或私有的,具體取決于它存在的位置。下面是緩存位置的列表
您可能已經(jīng)注意到,當(dāng)您單擊瀏覽器中的后退按鈕時(shí),加載頁面所需的時(shí)間比第一次加載時(shí)所需的時(shí)間少; 這是瀏覽器緩存中播放。瀏覽器緩存是緩存的最常見位置,瀏覽器通常為它保留一些空間。
瀏覽器緩存僅限于一個(gè)用戶,與其他緩存不同,它可以存儲(chǔ)“私有”響應(yīng)。稍后再談。
與為單個(gè)用戶提供服務(wù)的瀏覽器緩存不同,代理緩存可以為訪問相同內(nèi)容的數(shù)百個(gè)不同用戶提供服務(wù)。它們通常由ISP或任何其他獨(dú)立實(shí)體在更廣泛的層面上實(shí)施。
反向代理緩存或代理緩存在源服務(wù)器附近實(shí)現(xiàn),以減少服務(wù)器上的負(fù)載。不同于由ISP等實(shí)現(xiàn)的代理緩存以減少網(wǎng)絡(luò)中的帶寬使用,代理或反向代理緩存由服務(wù)器管理員在源服務(wù)器附近實(shí)現(xiàn)以減少服務(wù)器上的負(fù)載。
雖然可以控制反向代理緩存(因?yàn)樗怯赡诜?wù)器上實(shí)現(xiàn)的),您不能避免或控制瀏覽器和代理緩存。如果您的網(wǎng)站未配置為正確使用這些緩存,它仍將使用在這些緩存上設(shè)置的默認(rèn)值進(jìn)行緩存。
那么,我們?nèi)绾慰刂芖eb緩存?每當(dāng)服務(wù)器發(fā)出一些響應(yīng),它伴隨著一些HTTP頭,以指導(dǎo)緩存是否以及如何緩存此響應(yīng)。內(nèi)容提供者必須確保返回正確的HTTP頭,以強(qiáng)制緩存如何緩存內(nèi)容。
在HTTP / 1.1和介紹之前Cache-Control,有一個(gè)Expires標(biāo)題,它只是一個(gè)時(shí)間戳告訴緩存一些內(nèi)容被認(rèn)為是新鮮的時(shí)間。此標(biāo)題的可能值是絕對到期日期; 其中日期必須為GMT。下面是示例頭
Expires: Mon, 13 Mar 2017 12:22:00 GMT
應(yīng)該注意的是,日期不能超過一年,如果日期格式錯(cuò)誤,內(nèi)容將被視為陳舊。此外,緩存上的時(shí)鐘必須與服務(wù)器上的時(shí)鐘同步,否則可能無法實(shí)現(xiàn)所需的結(jié)果。
雖然,Expires頭仍然有效并且被緩存廣泛支持,應(yīng)該優(yōu)先考慮它的HTTP / 1.1后繼Cache-Control。
另一個(gè)從老,前HTTP / 1.1天,是Pragma?,F(xiàn)在可以使用下面給出的緩存控制頭來做一切。但是,我想指出的一點(diǎn)是,你可能會(huì)Pragma: no-cache在這里和那里使用,希望阻止緩存的響應(yīng)。它可能不一定工作; 因?yàn)镠TTP規(guī)范在請求頭中討論它,并且在響應(yīng)頭中沒有提及它。而Cache-Control頭應(yīng)該用于控制緩存。
高速緩存控制指定內(nèi)容被高速緩存的時(shí)間和方式。這個(gè)頭文件系列是在HTTP / 1.1中引入的,以克服Expires頭文件的限制。
Cache-Control頭的值是復(fù)合的,即它可以有多個(gè)指令/值。讓我們看看這個(gè)頭可能包含的值。
設(shè)置緩存private意味著內(nèi)容不會(huì)被緩存在任何代理中,它只會(huì)被客戶端(即瀏覽器)緩存,
Cache-Control: private
話雖如此,不要讓它欺騙你,認(rèn)為設(shè)置此標(biāo)題將使您的數(shù)據(jù)安全; 您仍然必須使用SSL來實(shí)現(xiàn)此目的。
如果設(shè)置為public,除了被客戶端緩存,它也可以由代理高速緩存; 服務(wù)于許多其他用戶
Cache-Control: public
no-store 指定內(nèi)容不被任何高速緩存高速緩存
Cache-Control: no-store
no-cache表示可以維護(hù)緩存,但是緩存的內(nèi)容將ETag在被服務(wù)之前從服務(wù)器被重新驗(yàn)證(例如使用)。也就是說,仍然存在對服務(wù)器的請求,但是用于驗(yàn)證并且不下載緩存的內(nèi)容。
Cache-Control: max-age=3600, no-cache, public
max-age指定內(nèi)容將被緩存的秒數(shù)。例如,如果cache-control看起來像下面:
Cache-Control: max-age=3600, public
這將意味著內(nèi)容是公開可緩存的,并且在60秒后將被認(rèn)為是陳舊的
s-maxage這里的s-前綴代表共享。這個(gè)指令專門針對共享緩存。像max-age它也得到的東西被緩存的秒數(shù)。如果存在,它將覆蓋max-age和expires頭的共享緩存。
Cache-Control: s-maxage=3600, public
must-revalidate有時(shí)可能會(huì)發(fā)生,如果您有網(wǎng)絡(luò)問題,并且無法從服務(wù)器檢索內(nèi)容,瀏覽器可能無法驗(yàn)證服務(wù)陳舊的內(nèi)容。must-revalidate避免這種情況。如果存在此偽指令,則意味著在任何情況下都不能提供過時(shí)的內(nèi)容,并且在服務(wù)之前必須從服務(wù)器重新驗(yàn)證數(shù)據(jù)。
Cache-Control: max-age=3600, public, must-revalidate
proxy-revalidate類似,must-revalidate但它為共享或代理緩存指定相同。換句話說proxy-revalidate就是must-revalidate為s-maxage是max-age。但為什么他們不叫它s-revalidate?我不知道為什么,如果你有任何線索請?jiān)谙旅媪粝略u論。
但是,您可以結(jié)合不同的方式這些指令來實(shí)現(xiàn)不同的緩存行為,no-cache/no-store并且public/private是互斥的。
如果同時(shí)指定no-store和no-cache,no-store將優(yōu)先于no-cache。
; If specified both Cache-Control: no-store, no-cache ; Below will be considered Cache-Control: no-store
對于private/public任何未認(rèn)證的請求,考慮緩存,public并且對于任何已認(rèn)證的緩存,考慮緩存private。
到目前為止,我們只討論了內(nèi)容如何緩存以及緩存內(nèi)容被視為新鮮的時(shí)間,但我們沒有討論客戶端如何從服務(wù)器進(jìn)行驗(yàn)證。下面我們討論用于這個(gè)目的的頭。
Etag或“實(shí)體標(biāo)簽”在HTTP / 1.1規(guī)范中引入。Etag只是服務(wù)器附加一些資源的唯一標(biāo)識(shí)符。此ETag稍后被客戶端用于進(jìn)行條件HTTP請求,"give me this resource if ETag is not same as the ETag that I have"并且僅當(dāng)etag不匹配時(shí)下載內(nèi)容。
在HTTP文檔中未指定生成ETag的方法,并且通常使用一些抗沖突哈希函數(shù)來為資源的每個(gè)版本分配etag。可能有兩種類型的etag,即強(qiáng)和弱
ETag: "j82j8232ha7sdh0q2882" - Strong Etag
ETag: W/"j82j8232ha7sdh0q2882" - Weak Etag (prefixed with `W/`)
強(qiáng)有效的ETag意味著兩個(gè)資源完全相同,它們之間沒有差別。雖然弱ETag意味著兩個(gè)資源雖然不完全相同但可以被認(rèn)為是相同的。例如,弱的etag可能對動(dòng)態(tài)內(nèi)容有用。
現(xiàn)在你知道什么etags是什么,但瀏覽器如何做這個(gè)請求?通過向服務(wù)器發(fā)出請求,同時(shí)在If-None-Match頭中發(fā)送可用的Etag 。
考慮這種情況,你打開一個(gè)網(wǎng)頁,加載了一個(gè)標(biāo)志圖像,緩存周期為60秒,ETag為abc123xyz。大約30分鐘后你重新加載頁面,瀏覽器會(huì)注意到,新鮮的60秒的標(biāo)志現(xiàn)在陳舊; 它將觸發(fā)對服務(wù)器的請求,在if-none-match標(biāo)題中發(fā)送陳舊的標(biāo)志圖像的ETag
If-None-Match: "abc123xyz"
然后服務(wù)器將該ETag與當(dāng)前資源版本的ETag進(jìn)行比較。如果兩個(gè)etag匹配,服務(wù)器將發(fā)送回的響應(yīng)304 Not Modified將告訴客戶端,它有它的副本仍然是好的,它會(huì)被認(rèn)為新鮮的另一個(gè)60秒。如果兩個(gè)etag不匹配,即徽標(biāo)可能改變,客戶端將被發(fā)送新的標(biāo)志,它將用來替換它所具有的陳舊的標(biāo)志。
服務(wù)器可能包含指示Last-Modified上次修改某些內(nèi)容的日期和時(shí)間的標(biāo)頭。
Last-Modified: Wed, 15 Mar 2017 12:30:26 GMT
當(dāng)內(nèi)容變得陳舊時(shí),客戶端將做出一個(gè)條件請求,包括在頭中調(diào)用If-Modified-Since到服務(wù)器以獲得更新Last-Modified日期的最后修改日期; 如果它與客戶端具有的日期匹配Last-Modified,則內(nèi)容的日期被更新為被認(rèn)為是新的另一n秒。如果接收的Last-Modified日期與客戶端具有的日期不匹配,則從服務(wù)器重新加載內(nèi)容并用客戶端具有的內(nèi)容替換。
If-Modified-Since: Wed, 15 Mar 2017 12:30:26 GMT
你現(xiàn)在可能會(huì)質(zhì)疑,如果緩存的內(nèi)容同時(shí)擁有Last-Modified并ETag分配給它?那么,在這種情況下,兩者都將被使用,即,不會(huì)有任何重新下載的資源,如果,只有當(dāng)ETag匹配新檢索到的,因此Last-Modified日期。如果ETag不匹配或Last-Modified大于來自服務(wù)器的內(nèi)容,則必須再次下載內(nèi)容。
現(xiàn)在我們已經(jīng)涵蓋了一切,讓我們把一切都放在透視,看看如何使用這些信息。
在我們介紹可能的緩存策略之前,讓我補(bǔ)充一點(diǎn),大多數(shù)服務(wù)器(包括Apache和Nginx)允許您通過服務(wù)器實(shí)現(xiàn)緩存策略,這樣您就不必與代碼中的標(biāo)頭交織。
例如,如果您使用Apache,并且您有靜態(tài)內(nèi)容/static,您可以將以下.htaccess文件放在目錄中,以使其中的所有內(nèi)容都使用以下方式緩存一年
# Cache everything for an year Header set Cache-Control "max-age=31536000, public"
您可以進(jìn)一步使用filesMatch指令來添加條件,并為不同類型的文件使用不同的緩存策略,例如
# Cache any images for one year <filesMatch ".(png|jpg|jpeg|gif)$"> Header set Cache-Control "max-age=31536000, public" </filesMatch> # Cache any CSS and JS files for a month <filesMatch ".(css|js)$"> Header set Cache-Control "max-age=2628000, public" </filesMatch>
或者如果您不想使用該.htaccess文件,您可以修改Apache的配置文件http.conf。同樣適用于Nginx,您可以在位置或服務(wù)器塊中添加緩存信息。
沒有關(guān)于你的緩存策略應(yīng)該看起來像什么黃金規(guī)則或設(shè)置標(biāo)準(zhǔn),每個(gè)應(yīng)用程序是不同的,你必須查找和找到最適合您的應(yīng)用程序。但是,只是給你一個(gè)大概的想法