認(rèn)識(shí)HTTP----緩存篇

本文內(nèi)容大多參考《圖解HTTP》一書

一. 認(rèn)識(shí)代理服務(wù)器

所以講緩存為什么要先扯代理服務(wù)器图仓?別急痢甘,讓我們看一下一個(gè)請(qǐng)求的簡(jiǎn)單示意圖。



我們看到客戶端(用戶)發(fā)送了一個(gè)請(qǐng)求并不是直接發(fā)給源服務(wù)器的而是經(jīng)過了代理服務(wù)器,然后經(jīng)由代理服務(wù)器再發(fā)送給源服務(wù)器,響應(yīng)也同樣遵循這個(gè)順序谭梗。
那么代理服務(wù)器在這中間擔(dān)任了什么角色?

1.1 代理服務(wù)器的分類

  • 緩存代理
    代理轉(zhuǎn)發(fā)響應(yīng)時(shí)宛蚓,緩存代理(Caching Proxy)會(huì)預(yù)先將資源的副本(緩存)保存在代理服務(wù)器上激捏。當(dāng)代理再次接收到對(duì)相同資源的請(qǐng)求時(shí),就可以不從源服務(wù)器那里
    獲取資源凄吏,而是將之前緩存的資源作為響應(yīng)返回远舅。
  • 透明代理(本文不做細(xì)致討論)
    轉(zhuǎn)發(fā)請(qǐng)求或響應(yīng)時(shí),不對(duì)報(bào)文做任何加工的代理類型被稱為透明代理(Transparent Proxy)痕钢。反之图柏,對(duì)報(bào)文內(nèi)容進(jìn)行加工的代理被稱為非透明代理。
瀏覽器盖喷、代理、服務(wù)器三者關(guān)系

二. 保存資源的緩存

緩存是指代理服務(wù)器或客戶端本地磁盤內(nèi)保存的資源副本难咕。利用緩存可減少對(duì)源服務(wù)器的訪問课梳,因此也就節(jié)省了通信流量和通信時(shí)間距辆。
緩存服務(wù)器是代理服務(wù)器的一種,并歸類在緩存代理類型中暮刃。換句話說跨算,當(dāng)代理轉(zhuǎn)發(fā)從服務(wù)器返回的響應(yīng)時(shí),代理服務(wù)器將會(huì)保存一份資源的副本椭懊。


緩存服務(wù)器的優(yōu)勢(shì)在于利用緩存可避免多次從源服務(wù)器轉(zhuǎn)發(fā)資源诸蚕。因此客戶端可就近從緩存服務(wù)器上獲取資源,而源服務(wù)器也不必多次處理相同的請(qǐng)求了氧猬。

1.1 緩存的有效期限

即便緩存服務(wù)器和客戶端內(nèi)有緩存背犯,也不能每次都給我返回緩存吧,如果是這樣盅抚,源服務(wù)器更新了我也不知道漠魏,因?yàn)槲颐看味际强淳彺娴馁Y源。
為了解決這個(gè)問題妄均,針對(duì)緩存設(shè)計(jì)了時(shí)效性的概念:
即使存在緩存柱锹,也會(huì)因?yàn)榭蛻舳说囊蟆⒕彺娴挠行诘纫蛩胤岚蛟捶?wù)器確認(rèn)資源的有效性禁熏。若判斷緩存失效,緩存服務(wù)器將會(huì)再次從源服務(wù)器上獲取“新”資源邑彪。


1.2 客戶端的緩存

緩存不僅可以存在于緩存服務(wù)器內(nèi)瞧毙,還可以存在客戶端瀏覽器中。以Internet Explorer 程序?yàn)槔啃睿芽蛻舳司彺娣Q為臨時(shí)網(wǎng)絡(luò)文件(Temporary Internet File)升筏。
瀏覽器緩存如果有效,就不必再向服務(wù)器請(qǐng)求相同的資源了瘸爽,可以直接從本地磁盤內(nèi)讀取您访。
另外,和緩存服務(wù)器相同的一點(diǎn)是剪决,當(dāng)判定緩存過期后灵汪,會(huì)向源服務(wù)器確認(rèn)資源的有效性。若判斷瀏覽器緩存失效柑潦,瀏覽器會(huì)再次請(qǐng)求新資源享言。


三. 與控制緩存相關(guān)的HTTP首部字段

1. http1.0 時(shí)代的緩存方式

Pragma

Pragma 是HTTP/1.1 之前版本的歷史遺留字段,僅作為與HTTP/1.0的向后兼容而定義渗鬼。
規(guī)范定義的形式唯一览露,如下所示。
Pragma: no-cache
該首部字段屬于通用首部字段譬胎,但只用在客戶端發(fā)送的請(qǐng)求中差牛∶客戶端會(huì)要求所有的中間服務(wù)器不返回緩存的資源。


所有的中間服務(wù)器如果都能以HTTP/1.1 為基準(zhǔn)偏化, 那直接采用Cache-Control: no-cache 指定緩存的處理方式是最為理想的脐恩。但要整體掌握全部中間服務(wù)器使用的HTTP 協(xié)議版本卻是不現(xiàn)實(shí)的。因此侦讨,發(fā)送的請(qǐng)求會(huì)同時(shí)含有下面兩個(gè)首部字段驶冒。

Cache-Control: no-cache
Pragma: no-cache

Expires


Expires: Wed, 04 Jul 2012 08:26:05 GMT
首部字段Expires 會(huì)將資源失效的日期告知客戶端。緩存服務(wù)器在接收到含有首部字段Expires 的響應(yīng)后韵卤,會(huì)以緩存來應(yīng)答請(qǐng)求骗污,在Expires 字段值指定的時(shí)間之前,響應(yīng)的副本會(huì)一直被保存怜俐。當(dāng)超過指定的時(shí)間后身堡,緩存服務(wù)器在請(qǐng)求發(fā)送過來時(shí),會(huì)轉(zhuǎn)向源服務(wù)器請(qǐng)求資源拍鲤。
源服務(wù)器不希望緩存服務(wù)器對(duì)資源緩存時(shí)贴谎,最好在Expires 字段內(nèi)寫入與首部字段Date 相同的時(shí)間值。
但是季稳,當(dāng)首部字段Cache-Control 有指定max-age 指令時(shí)擅这,比起首部字段Expires,會(huì)優(yōu)先處理max-age 指令景鼠。

2. Cache-Control

通過指定首部字段Cache-Control 的指令仲翎,就能操作緩存的工作機(jī)制。

首部字段Cache-Control 能夠控制緩存的行為

指令的參數(shù)是可選的铛漓,多個(gè)指令之間通過“,”分隔溯香。首部字段Cache-Control 的指令在請(qǐng)求和響應(yīng)下都適用。
Cache-Control: private, max-age=0, no-cache

2.1 Cache-Control指令一覽:

可用的指令按請(qǐng)求和響應(yīng)分類如下所示:

緩存請(qǐng)求指令

指令 參數(shù) 說明
no-cache 強(qiáng)制向源服務(wù)器再次驗(yàn)證
no-store 不緩存請(qǐng)求或響應(yīng)的任何內(nèi)容
max-age = [ 秒] 必須有 響應(yīng)的最大Age值
max-stale( = [ 秒]) 可省略 接收已過期的響應(yīng)
min-fresh = [ 秒] 必須有 期望在指定時(shí)間內(nèi)的響應(yīng)仍有效
no-transform 代理不可更改媒體類型
only-if-cached 從緩存獲取資源
cache-extension - 新指令標(biāo)記(token)

緩存響應(yīng)指令

指令 參數(shù) 說明
public 可向任意方提供響應(yīng)的緩存
private 可省略 僅向特定用戶返回響應(yīng)
no-cache 可省略 緩存前必須先確認(rèn)其有效性
no-store 不緩存請(qǐng)求或響應(yīng)的任何內(nèi)容
no-transform 代理不可更改媒體類型
must-revalidate 可緩存但必須再向源服務(wù)器進(jìn)行確認(rèn)
proxy-revalidate 要求緩存服務(wù)器對(duì)緩存的響應(yīng)有效性再進(jìn)行確認(rèn)
max-age = [ 秒] 必須有 響應(yīng)的最大Age值
s-maxage = [ 秒] 必須有 公共緩存服務(wù)器響應(yīng)的最大Age值
cache-extension - 新指令標(biāo)記(token)

2.2 Cache-Control指令詳細(xì)介紹

2.2.1. 表示是否能緩存的指令

public指令
Cache-Control: public
當(dāng)指定使用public 指令時(shí)浓恶,則明確表明其他用戶也可利用緩存玫坛。
private指令


Cache-Control: private
當(dāng)指定private 指令后,響應(yīng)只以特定的用戶作為對(duì)象包晰,這與public
指令的行為相反湿镀。
緩存服務(wù)器會(huì)對(duì)該特定用戶提供資源緩存的服務(wù),對(duì)于其他用戶發(fā)
送過來的請(qǐng)求伐憾,代理服務(wù)器則不會(huì)返回緩存勉痴。
no-cache指令

Cache-Control: no-cache
使用no-cache 指令的目的是為了防止從緩存中返回過期的資源∈魉啵客戶端發(fā)送的請(qǐng)求中如果包含no-cache 指令蒸矛,則表示客戶端將不會(huì)接收緩存過的響應(yīng)。于是,“中間”的緩存服務(wù)器必須把客戶端請(qǐng)求轉(zhuǎn)發(fā)給源服務(wù)器雏掠。
如果服務(wù)器返回的響應(yīng)中包含no-cache 指令廓脆,那么緩存服務(wù)器不能對(duì)資源進(jìn)行緩存。源服務(wù)器以后也將不再對(duì)緩存服務(wù)器請(qǐng)求中提出的資源有效性進(jìn)行確認(rèn)磁玉,且禁止其對(duì)響應(yīng)資源進(jìn)行緩存操作。
Cache-Control: no-cache=Location
由服務(wù)器返回的響應(yīng)中驾讲,若報(bào)文首部字段Cache-Control 中對(duì)no-cache字段名具體指定參數(shù)值蚊伞,那么客戶端在接收到這個(gè)被指定參數(shù)值的首部字段對(duì)應(yīng)的響應(yīng)報(bào)文后,就不能使用緩存吮铭。換言之时迫,無參數(shù)值的首部字段可以使用緩存。只能在響應(yīng)指令中指定該參數(shù)谓晌。

2.2.2. 控制可執(zhí)行緩存的對(duì)象的指令

no-store指令
Cache-Control: no-store
當(dāng)使用no-store 指令時(shí)掠拳,暗示請(qǐng)求(和對(duì)應(yīng)的響應(yīng))或響應(yīng)中包含機(jī)密信息。
因此纸肉,該指令規(guī)定緩存不能在本地存儲(chǔ)請(qǐng)求或響應(yīng)的任一部分溺欧。

ps:從字面意思上很容易把no-cache誤解成為不緩存,但事實(shí)上no-cache代表不緩存過期的資源柏肪,緩存會(huì)向源服務(wù)器進(jìn)行有效期確認(rèn)后處理資源姐刁,也許稱為do-not-serve-from-cache-without-revalidation更合適。no-store 才是真正地不進(jìn)行緩存烦味,請(qǐng)讀者注意區(qū)別理解聂使。

2.2.3. 指定緩存期限和認(rèn)證的指令

s-maxage指令
Cache-Control: s-maxage=604800 //(單位:秒)
s-maxage 指令的功能和max-age 指令的功能相同, 它們的不同點(diǎn)是s-maxage 指令只適用于供多位用戶使用的公共緩存服務(wù)器(這里指代理服務(wù)器)谬俄。也就是說柏靶,對(duì)于向同一用戶重復(fù)返回響應(yīng)的服務(wù)器來說,這個(gè)指令沒有任何作用溃论。
另外屎蜓,當(dāng)使用s-maxage 指令后,則直接忽略對(duì)Expires 首部字段及max-age 指令的處理蔬芥。
max-age指令


Cache-Control: max-age=604800 //(單位:秒)
當(dāng)客戶端發(fā)送的請(qǐng)求中包含max-age 指令時(shí)梆靖,如果判定緩存資源的緩存時(shí)間數(shù)值比指定時(shí)間的數(shù)值更小,那么客戶端就接收緩存的資源笔诵。
另外返吻,當(dāng)指定max-age 值為0,那么緩存服務(wù)器通常需要將請(qǐng)求轉(zhuǎn)發(fā)給源服務(wù)器乎婿。
當(dāng)服務(wù)器返回的響應(yīng)中包含max-age 指令時(shí)测僵,緩存服務(wù)器將不對(duì)資源的有效性再作確認(rèn),而max-age 數(shù)值代表資源保存為緩存的最長(zhǎng)時(shí)間。
應(yīng)用HTTP/1.1 版本的緩存服務(wù)器遇到同時(shí)存在Expires 首部字段的情況時(shí)捍靠,會(huì)優(yōu)先處理max-age 指令沐旨,而忽略掉Expires 首部字段。而HTTP/1.0 版本的緩存服務(wù)器的情況卻相反榨婆,max-age 指令會(huì)被忽略掉磁携。
min-fresh指令

Cache-Control: min-fresh=60 //(單位:秒)
min-fresh 指令要求緩存服務(wù)器返回至少還未過指定時(shí)間的緩存資源。
比如良风,當(dāng)指定min-fresh 為60 秒后谊迄,過了60 秒的資源都無法作為響應(yīng)返回了。
max-stale指令
Cache-Control: max-stale=3600 //(單位:秒)
使用max-stale 可指示緩存資源烟央,即使過期也照常接收统诺。
如果指令未指定參數(shù)值,那么無論經(jīng)過多久疑俭,客戶端都會(huì)接收響應(yīng)粮呢;如果指令中指定了具體數(shù)值,那么即使過期钞艇,只要仍處于max-stale 指定的時(shí)間內(nèi)啄寡,仍舊會(huì)被客戶端接收。
only-if-cached指令
Cache-Control: only-if-cached
使用only-if-cached 指令表示客戶端僅在緩存服務(wù)器本地緩存目標(biāo)資源的情況下才會(huì)要求其返回哩照。換言之这难,該指令要求緩存服務(wù)器不重新加載響應(yīng),也不會(huì)再次確認(rèn)資源有效性葡秒。若發(fā)生請(qǐng)求緩存服務(wù)器的本地緩存無響應(yīng)姻乓,則返回狀態(tài)碼504 Gateway Timeout。
must-revalidate指令
Cache-Control: must-revalidate
使用must-revalidate 指令眯牧,代理會(huì)向源服務(wù)器再次驗(yàn)證即將返回的響應(yīng)緩存目前是否仍然有效蹋岩。
若代理無法連通源服務(wù)器再次獲取有效資源的話,緩存必須給客戶端一條504(Gateway Timeout)狀態(tài)碼学少。
另外剪个,使用must-revalidate 指令會(huì)忽略請(qǐng)求的max-stale 指令(即使已經(jīng)在首部使用了max-stale,也不會(huì)再有效果)版确。
proxy-revalidate指令
Cache-Control: proxy-revalidate
proxy-revalidate 指令要求所有的緩存服務(wù)器在接收到客戶端帶有該指令的請(qǐng)求返回響應(yīng)之前扣囊,必須再次驗(yàn)證緩存的有效性。
no-transform指令
Cache-Control: no-transform
使用no-transform 指令規(guī)定無論是在請(qǐng)求還是響應(yīng)中绒疗,緩存都不能改變實(shí)體主體的媒體類型侵歇。這樣做可防止緩存或代理壓縮圖片等類似操作。

2.2.4. Cache-Control 擴(kuò)展

cache-extension token
Cache-Control: private, community="UCI"
通過 cache-extension 標(biāo)記(token)吓蘑,可以擴(kuò)展Cache-Control 首部字段內(nèi)的指令惕虑。
如上例坟冲,Cache-Control 首部字段本身沒有community 這個(gè)指令。借助extension tokens 實(shí)現(xiàn)了該指令的添加溃蔫。如果緩存服務(wù)器不能理community 這個(gè)新指令健提,就會(huì)直接忽略。因此伟叛,extension tokens 僅對(duì)能理解它的緩存服務(wù)器來說是有意義的私痹。

3. Last-Modified


Last-Modified: Wed, 23 May 2012 09:59:55 GMT
服務(wù)器將資源傳遞給客戶端時(shí),會(huì)將資源最后更改的時(shí)間以“Last-Modified: GMT”的形式加在實(shí)體首部上一起返回給客戶端统刮。
當(dāng)客戶端對(duì)同樣的資源發(fā)起同樣的請(qǐng)求時(shí)侄榴,會(huì)把該信息附帶在請(qǐng)求報(bào)文中一并帶給服務(wù)器去做檢查。

3.1 If-Modified-Since


如果在If-Modified-Since 字段指定的日期時(shí)間后网沾,資源發(fā)生了更新,服務(wù) 器會(huì)接受請(qǐng)求

If-Modified-Since: Thu, 15 Apr 2004 00:00:00 GMT
首部字段If-Modified-Since蕊爵,屬附帶條件之一辉哥,它會(huì)告知服務(wù)器若If-Modified-Since 字段值早于資源的更新時(shí)間,則希望能處理該請(qǐng)求攒射。而在指定If-Modified-Since 字段值的日期時(shí)間之后醋旦,如果請(qǐng)求的資源都沒有過更新,則返回狀態(tài)碼304 Not Modified 的響應(yīng)会放。
If-Modified-Since 用于確認(rèn)代理或客戶端擁有的本地資源的有效性饲齐。獲取資源的更新日期時(shí)間,可通過確認(rèn)首部字段Last-Modified 來確定咧最。

3.2 If-Unmodified-Since

If-Unmodified-Since: Thu, 03 Jul 2012 00:00:00 GMT
首部字段If-Unmodified-Since 和首部字段If-Modified-Since 的作用相反捂人。它的作用的是告知服務(wù)器,指定的請(qǐng)求資源只有在字段值內(nèi)指定的日期時(shí)間之后矢沿,未發(fā)生更新的情況下滥搭,才能處理請(qǐng)求。如果在指定日期時(shí)間后發(fā)生了更新捣鲸,則以狀態(tài)碼412 Precondition Failed 作為響應(yīng)返回瑟匆。

ps:Last-Modified 存在一定問題,如果在服務(wù)器上栽惶,一個(gè)資源被修改了愁溜,但其實(shí)際內(nèi)容根本沒發(fā)生改變,會(huì)因?yàn)長(zhǎng)ast-Modified時(shí)間匹配不上而返回了整個(gè)實(shí)體給客戶端(即使客戶端緩存里有個(gè)一模一樣的資源)外厂。

4. ETag


ETag: "82e22293907ce725faf67773957acd12"
首部字段ETag 能告知客戶端實(shí)體標(biāo)識(shí)冕象。它是一種可將資源以字符串形式做唯一性標(biāo)識(shí)的方式。服務(wù)器會(huì)為每份資源分配對(duì)應(yīng)的ETag 值汁蝶。
另外交惯,當(dāng)資源更新時(shí),ETag 值也需要更新。生成ETag 值時(shí)席爽,并沒有統(tǒng)一的算法規(guī)則意荤,而僅僅是由服務(wù)器來分配。

資源被緩存時(shí)只锻,就會(huì)被分配唯一性標(biāo)識(shí)玖像。
例如,當(dāng)使用中文版的瀏覽器訪問 http : //www.google.com/ 時(shí)齐饮,就會(huì)返回中文版對(duì)應(yīng)的資源捐寥,而使用英文版的瀏覽器訪問時(shí),則會(huì)返回英文版對(duì)應(yīng)的資源祖驱。
兩者的URI是相同的握恳,所以僅憑URI 指定緩存的資源是相當(dāng)困難的。若在下載過程中出現(xiàn)連接中斷捺僻、再連接的情況乡洼,都會(huì)依照ETag 值來指定資源。

4.1 強(qiáng)ETag 值和弱Tag 值

  • 強(qiáng)ETag 值
    強(qiáng)ETag 值匕坯,不論實(shí)體發(fā)生多么細(xì)微的變化都會(huì)改變其值束昵。
    ETag: "usagi-1234"

  • 弱ETag 值
    弱ETag 值只用于提示資源是否相同。只有資源發(fā)生了根本改變葛峻,產(chǎn)
    生差異時(shí)才會(huì)改變ETag 值锹雏。這時(shí),會(huì)在字段值最開始處附加W/术奖。
    ETag: W/"usagi-1234"

4.2 If-Match

附帶條件請(qǐng)求

形如If-xxx 這種樣式的請(qǐng)求首部字段礁遵,都可稱為條件請(qǐng)求。服務(wù)器接收到附帶條件的請(qǐng)求后采记,只有判斷指定條件為真時(shí)榛丢,才會(huì)執(zhí)行請(qǐng)求。

只有當(dāng)If-Match 的字段值跟ETag 值匹配一致時(shí)挺庞,服務(wù)器才會(huì)接受請(qǐng)求

If-Match: "123456"
首部字段If-Match晰赞,屬附帶條件之一,它會(huì)告知服務(wù)器匹配資源所用的實(shí)體標(biāo)記(ETag)值选侨。這時(shí)的服務(wù)器無法使用弱ETag 值掖鱼。
服務(wù)器會(huì)比對(duì)If-Match 的字段值和資源的ETag 值,僅當(dāng)兩者一致時(shí)援制,才會(huì)執(zhí)行請(qǐng)求戏挡。反之,則返回狀態(tài)碼412 Precondition Failed 的響應(yīng)晨仑。
還可以使用星號(hào)(*)指定If-Match 的字段值褐墅。針對(duì)這種情況拆檬,服務(wù)器將會(huì)忽略ETag 的值,只要資源存在就處理請(qǐng)求妥凳。

4.3 If-None-Match

只有在If-None-Match 的字段值與ETag 值不一致時(shí)竟贯, 可處理該請(qǐng)求。 與If-Match 首部字段的作用相反

首部字段If-None-Match 屬于附帶條件之一逝钥。它和首部字段If-Match 作用相反屑那。用于指定If-None-Match 字段值的實(shí)體標(biāo)記(ETag)值與請(qǐng)求資源的ETag 不一致時(shí),它就告知服務(wù)器處理該請(qǐng)求艘款。
在GET 或HEAD 方法中使用首部字段If-None-Match 可獲取最新的資源持际。因此,這與使用首部字段If-Modified-Since 時(shí)有些類似哗咆。

5. 用戶刷新/訪問行為

5.1 在URI輸入欄中輸入然后回車

不與服務(wù)器確認(rèn)蜘欲,而是直接使用瀏覽器緩存的內(nèi)容。其中響應(yīng)內(nèi)容和之前的響應(yīng)內(nèi)容一模一樣晌柬,例如其中的Date時(shí)間是上一次響應(yīng)的時(shí)間姥份。

5.2 F5/點(diǎn)擊工具欄中的刷新按鈕/右鍵菜單重新加載

F5的作用和直接在URI輸入欄中輸入然后回車是不一樣的,F(xiàn)5會(huì)讓瀏覽器無論如何都發(fā)一個(gè)HTTP Request給Server空繁,即使先前的響應(yīng)中有Expires頭部。

5.3 Ctl+F5

Ctrl+F5要的是徹底的從Server拿一份新的資源過來朱庆,所以不光要發(fā)送HTTP request給Server盛泡,而且這個(gè)請(qǐng)求里面連If-Modified-Since/If-None-Match都沒有,這樣就逼著Server不能返回304娱颊,而是把整個(gè)資源原原本本地返回一份傲诵,這樣,Ctrl+F5引發(fā)的傳輸時(shí)間變長(zhǎng)了箱硕,自然網(wǎng)頁Refresh的也慢一些拴竹。

6. 緩存實(shí)踐

6.1 Expires / Cache-Control

Cache-Control 是 HTTP1.1 才有的,不適用于 HTTP1.0剧罩,而 Expires 既適用于 HTTP1.0栓拜,也適用于 HTTP1.1,所以說在大多數(shù)情況下同時(shí)發(fā)送這兩個(gè)頭會(huì)是一個(gè)更好的選擇惠昔,當(dāng)客戶端兩種頭都能解析的時(shí)候幕与,會(huì)優(yōu)先使用 Cache-Control。

6.2 Last-Modified / ETag

二者都是通過某個(gè)標(biāo)識(shí)值來請(qǐng)求資源镇防, 如果服務(wù)器端的資源沒有變化啦鸣,則自動(dòng)返回 HTTP 304 (Not Changed)狀態(tài)碼,內(nèi)容為空来氧,這樣就節(jié)省了傳輸數(shù)據(jù)量诫给。當(dāng)資源變化后則返回新資源香拉。從而保證不向客戶端重復(fù)發(fā)出資源,也保證當(dāng)服務(wù)器有變化時(shí)中狂,客戶端能夠得到最新的資源凫碌。
其中Last-Modified使用文件最后修改作為文件標(biāo)識(shí)值,它無法處理文件一秒內(nèi)多次修改的情況吃型,而且只要文件修改了哪怕文件實(shí)質(zhì)內(nèi)容沒有修改证鸥,也會(huì)重新返回資源內(nèi)容;ETag作為“被請(qǐng)求變量的實(shí)體值”勤晚,其完全可以解決Last-Modified頭部的問題枉层,但是其計(jì)算過程需要耗費(fèi)服務(wù)器資源。

6.3 from-cache / 304

Expires和Cache-Control都有一個(gè)問題就是服務(wù)端的修改赐写,如果還在緩存時(shí)效里鸟蜡,那么客戶端是不會(huì)去請(qǐng)求服務(wù)端資源的(非刷新),這就存在一個(gè)資源版本不符的問題挺邀,而強(qiáng)制刷新一定會(huì)發(fā)起HTTP請(qǐng)求并返回資源內(nèi)容揉忘,無論該內(nèi)容在這段時(shí)間內(nèi)是否修改過;而Last-Modified和Etag每次請(qǐng)求資源都會(huì)發(fā)起請(qǐng)求端铛,哪怕是很久都不會(huì)有修改的資源泣矛,都至少有一次請(qǐng)求響應(yīng)的消耗。
對(duì)于所有可緩存資源禾蚕,指定一個(gè)Expires或Cache-Control max-age以及一個(gè)Last-Modified或ETag至關(guān)重要您朽。同時(shí)使用前者和后者可以很好的相互適應(yīng)。
前者不需要每次都發(fā)起一次請(qǐng)求來校驗(yàn)資源時(shí)效性换淆,后者保證當(dāng)資源未出現(xiàn)修改的時(shí)候不需要重新發(fā)送該資源哗总。而在用戶的不同刷新頁面行為中,二者的結(jié)合也能很好的利用HTTP緩存控制特性倍试,無論是在地址欄輸入U(xiǎn)RI然后輸入回車進(jìn)行訪問讯屈,還是點(diǎn)擊刷新按鈕,瀏覽器都能充分利用緩存內(nèi)容县习,避免進(jìn)行不必要的請(qǐng)求與數(shù)據(jù)傳輸涮母。

6.4 避免304

做法很簡(jiǎn)單,就是把可能會(huì)更新的資源以版本形式發(fā)布躁愿,常用的方法是在文件名或參數(shù)帶上一串md5或時(shí)間標(biāo)記符:

https://#/hm.js?e23800c454aa573c0ccb16b52665ac26
http://tb1.bdstatic.com/tb/_/tbean_safe_ajax_94e7ca2.js
http://img1.gtimg.com/ninja/2/2016/04/ninja145972803357449.jpg

可以看到上面的例子中有不同的做法哈蝇,有的在URI后面加上了md5參數(shù),有的將md5值作為文件名的一部分攘已,有的將資源放在特性版本的目錄中炮赦。
那么在文件沒有變動(dòng)的時(shí)候,瀏覽器不用發(fā)起請(qǐng)求直接可以使用緩存文件样勃;而在文件有變化的時(shí)候吠勘,由于文件版本號(hào)的變更性芬,導(dǎo)致文件名變化,請(qǐng)求的url變了剧防,自然文件就更新了植锉。這樣能確保客戶端能及時(shí)從服務(wù)器收取到新修改的文件峭拘。通過這樣的處理俊庇,增長(zhǎng)了靜態(tài)資源,特別是圖片資源的緩存時(shí)間鸡挠,避免該資源很快過期辉饱,客戶端頻繁向服務(wù)端發(fā)起資源請(qǐng)求,服務(wù)器再返回304響應(yīng)的情況(有Last-Modified/Etag)拣展。

7 參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末彭沼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子备埃,更是在濱河造成了極大的恐慌姓惑,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件按脚,死亡現(xiàn)場(chǎng)離奇詭異于毙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辅搬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門唯沮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伞辛,你說我怎么就攤上這事烂翰『蝗保” “怎么了蚤氏?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)踊兜。 經(jīng)常有香客問我竿滨,道長(zhǎng),這世上最難降的妖魔是什么捏境? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任于游,我火速辦了婚禮,結(jié)果婚禮上垫言,老公的妹妹穿的比我還像新娘贰剥。我一直安慰自己,他們只是感情好筷频,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布蚌成。 她就那樣靜靜地躺著前痘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪担忧。 梳的紋絲不亂的頭發(fā)上芹缔,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音瓶盛,去河邊找鬼最欠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惩猫,可吹牛的內(nèi)容都是我干的芝硬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼帆锋,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼吵取!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锯厢,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤皮官,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后实辑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捺氢,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年剪撬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了摄乒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡残黑,死狀恐怖馍佑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情梨水,我是刑警寧澤拭荤,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站疫诽,受9級(jí)特大地震影響舅世,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奇徒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一雏亚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧摩钙,春花似錦罢低、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宜肉。三九已至,卻和暖如春翎碑,著一層夾襖步出監(jiān)牢的瞬間谬返,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工日杈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留遣铝,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓莉擒,卻偏偏與公主長(zhǎng)得像酿炸,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子涨冀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容