HTTP詳細總結
一磺浙、前言
URI
URI(統(tǒng)一資源標識符):我們使用HTTP協(xié)議,主要就用來訪問互聯(lián)網(wǎng)上的各種資源徒坡,而URI就用來標識這些資源在互聯(lián)網(wǎng)上的位置撕氧,包括兩種最常見的方式:URL和URN。
語法:{方案或協(xié)議} {主機+端口} {路徑} {查詢} {錨點}
例如:http://www.example.com:80/path/to/myfile.html?key1=value2&key2=value2#title
喇完,
協(xié)議
協(xié)議:http://
告訴瀏覽器采用何種協(xié)議伦泥,常見的協(xié)議有:
協(xié)議 | 描述 | 作用 |
---|---|---|
data | Data URIs | |
file | 本地文件傳輸協(xié)議 | 訪問本地計算機中的文件 |
ftp | 文件傳輸協(xié)議 | 主要用于遠程文件傳輸 |
http/https | 超文本傳輸協(xié)議/安全的超文本傳輸協(xié)議 | |
mailto | 電子郵件協(xié)議 | 用于通知瀏覽器調(diào)用本地郵件客戶端發(fā)送郵件 |
ssh | 安全外殼協(xié)議 | 提供安全加密的網(wǎng)絡傳輸環(huán)境 |
tel | 電話協(xié)議 | 用于通知瀏覽器調(diào)用本地電話客戶端發(fā)起通話請求 |
urn | 統(tǒng)一資源名稱 | 統(tǒng)一資源名稱 |
view-source | 資源源代碼 | 后接資源url可以查看資源源代碼 |
ws/wss | WebSocket連接協(xié)議 | websocket |
MIME類型 {#mime}
多用途Internet郵件擴展(MIME)類型 是一種標準化的方式來表示文檔的性質(zhì)和格式。在Windows上我們通常使用文件擴展名來區(qū)分使用何種軟件來處理文檔锦溪,而瀏覽器通常使用MIME類型(而不是文件擴展名)來確定如何處理文檔不脯,所以服務器應該在響應對象的頭部設置正確的MIME類型。
-
語法:type/subtype
MIME的組成結構非常簡單刻诊;由類型與子類型兩個字符串中間用'/'分隔而組成防楷。不允許空格存在。type 表示可以被分多個子類的獨立類別则涯。subtype 表示細分后的每個類型复局。
MIME對大小寫不敏感,但是通常使用全小寫形式粟判。 -
獨立類型:獨立類型表明了對文件的分類亿昏,有如下幾種:
類型 描述 典型實例 text 普通文本 text/plain;text/html;text/css image 圖像,包括動圖 image/gif;image/png;image/jpeg;image/bmp audio 音頻 audio/midi;audio/mpeg;audio/ogg video 視頻 video/webm;video/ogg application 某種二進制數(shù)據(jù) application/octet-stream;application/xml;application/pdf 對于text類型档礁,如果沒有特定的子類型角钩,則默認text/plain;類似的呻澜,application類型默認為application/octet-stream递礼。
-
Multipart類型:復合文件一種類型。
multipart/form-data:用于表示表單POST時的數(shù)據(jù)易迹。
-
multipart/byteranges:用于把部分的響應報文發(fā)送回瀏覽器宰衙。
使用狀態(tài)碼206 Partial Content來發(fā)送整個文件的子集平道,而HTTP對不能處理的復合文件使用特殊的方式:將信息直接傳送給瀏覽器(這時可能會建立一個“另存為”窗口睹欲,但是卻不知道如何去顯示內(nèi)聯(lián)文件。)一屋。當發(fā)送狀態(tài)碼206Partial Content 時窘疮,這個MIME類型用于指出這個文件由若干部分組成,每一個都有其請求范圍冀墨。就像其他很多類型Content-Type使用分隔符來制定分界線闸衫。每一個不同的部分都有Content-Type這樣的HTTP頭來說明文件的實際類型,以及 Content-Range來說明其范圍诽嘉。
-
幾種重要的MIME類型
- text/plain:純文本
- text/css:css樣式表文件
- text/html:html文件
- application/octet-stream:二進制流
- application/javascript:js文件
- application/json:json文件
- application/xml:xml文件
- application/pdf:pdf文件
- multipart/form-data:表單提交
如下為一個包含附件的提交:
以上請求需注意的是蔚出,Content-Type為multipart/form-data弟翘,且請求體里可以看到,除上傳文件CustomMethod.dll外骄酗,還包括property1和property2兩對值一并提交了稀余。POST /site/file/upload HTTP/1.1 Host: myhost Connection: keep-alive Content-Length: 46492 Origin: http://myhost User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5jBgoLfQFCAe9xpw Accept: */* Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: Company_ID=EINK; ------WebKitFormBoundary5jBgoLfQFCAe9xpw Content-Disposition: form-data; name="property1" CustomMethod.dll ------WebKitFormBoundary5jBgoLfQFCAe9xpw Content-Disposition: form-data; name="property2" 30 ------WebKitFormBoundary5jBgoLfQFCAe9xpw Content-Disposition: form-data; name="file"; filename="CustomMethod.dll" Content-Type: application/x-msdownload ------WebKitFormBoundary5jBgoLfQFCAe9xpw--
-
幾種可能會用到的MIME類型
- image/jpeg:jpeg、jpg文件
- image/gif:gif文件
- image/x-ico:icon圖標文件
- application/msword:Word文件
- application/vnd.ms-excel:excel文件
- application/x-rar-compressed:rar文件
-
設置正確MIME類型的重要性
再次重申趋翻,瀏覽器是以MIME作為處理文件的依據(jù)睛琳,如果一個link標簽內(nèi)的css文件被指定為text/plain,瀏覽器不會將其解析為css文件踏烙。
二师骗、HTTP概覽
HTTP協(xié)議
HTTP協(xié)議(超文本傳輸協(xié)議)是互聯(lián)網(wǎng)上最廣泛的一種網(wǎng)絡協(xié)議。設計HTTP最初的目的是為了提供一種發(fā)布和接收HTML頁面的方法讨惩。通過HTTP或者HTTPS協(xié)議請求的資源由統(tǒng)一資源標識符來標識辟癌。
HTTP請求過程
客戶端(User-Agent)
一般為用戶瀏覽器。
服務端(Web-Server)
一臺或一組能提供Web服務的計算機荐捻。
代理(Proxies)
在瀏覽器和服務器之間有許多機器或設備轉(zhuǎn)發(fā)了HTTP消息愿待,這些設備分布于傳輸層、網(wǎng)絡層或者物理層上靴患,而有一些位于應用層仍侥,他們就是代理,代理對于客戶端和服務器來說既可以是透明的鸳君,也可以是可見的农渊。而代理既可能改變HTTP消息,也可能不改變或颊,這就要看代理的具體作用了砸紊。各種代理有如下幾種作用:
- 轉(zhuǎn)發(fā):單純不做任何操作,比如大多數(shù)企業(yè)內(nèi)網(wǎng)囱挑,通過一臺代理服務器來訪問外網(wǎng)醉顽。或?qū)⑻囟ㄕ埱筠D(zhuǎn)發(fā)到其他地址平挑。
- 緩存游添。
- 過濾:同樣一些企業(yè)內(nèi)網(wǎng)的代理會做一些反病毒掃描、家長控制等通熄。
- 認證:完成一些身份認證的工作唆涝,或者對不同資源進行權限管理。
- 日志:比如在現(xiàn)有系統(tǒng)不做改變的情況下唇辨,使用nginx代理實現(xiàn)日志記錄廊酣。
特點
- 可讀性:HTTP協(xié)議被設計的很簡單易讀。
- 可擴展:擴展性強赏枚,只需客戶端與服務器就新header達成一致即可輕易實現(xiàn)擴展亡驰。
- 無狀態(tài):HTTP是無狀態(tài)的晓猛,在同一個連接中的兩次連續(xù)的請求是沒有關系的。盡管如此凡辱,仍然可以通過把cookie添加到header中獲取上下文信息來解決此問題鞍帝。
作用
- 緩存:使用cache相關的header等來控制緩存。服務端能告訴瀏覽器或代理哪些文檔需要被緩存煞茫,緩存多久帕涌;同時瀏覽器也能告訴代理哪些文檔請求需要忽略。
- 認證:使用Authenticate相似的頭部即可實現(xiàn)對特定的頁面進行保護续徽,同時也可以通過cookie來實現(xiàn)相應功能蚓曼。
- 代理:代理就是基于HTTP或socket層面。
- 會話:使用cookie來傳遞上下文信息钦扭。
- 開放同源策略:可以通過修改HTTP頭部一些信息解除同源限制纫版。
三、HTTP報文
HTTP會話包括客戶端發(fā)送請求客情、建立連接其弊、服務端返回響應,建立連接發(fā)生在傳輸層膀斋,通常為TCP連接梭伐,默認80端口。C-S模型不允許服務器在沒有顯示發(fā)送請求時向客戶端發(fā)送數(shù)據(jù)仰担,不過現(xiàn)在開發(fā)使用其他技術糊识,如XMLHTTPRequest或Fetch API周期性地請求服務器,以達到類似效果摔蓝。
客戶端發(fā)送請求與服務端返回響應分別對應HTTP報文中得請求報文和響應報文赂苗。
HTTP請求報文
HTTP請求報文包括請求行、請求頭贮尉、空行和請求體四部分組成拌滋,空行用來隔開請求頭與請求體,如下圖:
百度首頁的請求頭如下:
GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: BAIDUID=51DCFC83838328932381GS62F770DA7:FG=1;
請求行
請求行由請求的HTTP方法猜谚、路徑败砂、協(xié)議版本三部分組成。
請求方法有:GET龄毡、POST吠卷、PUT锡垄、DELETE沦零、HEAD、CONNECT货岭、OPTIONS路操、TRACE疾渴、PATCH。常用的有GET屯仗、POST搞坝、PUT、DELETE魁袜。
- GET:GET方法請求一個指定資源的表示形式. 使用GET的請求應該只被用于獲取數(shù)據(jù)桩撮。
- HEAD:HEAD方法請求一個與GET請求的響應相同的響應,但沒有響應體峰弹。
- POST:POST方法用于將實體提交到指定的資源店量,通常導致狀態(tài)或服務器上的副作用的更改。
- PUT:PUT方法用請求有效載荷替換目標資源的所有當前表示鞠呈。
- DELETE:DELETE方法刪除指定的資源融师。
- CONNECT:CONNECT方法建立一個到由目標資源標識的服務器的隧道。
- OPTIONS:OPTIONS方法用于描述目標資源的通信選項蚁吝。
- TRACE:TRACE方法沿著到目標資源的路徑執(zhí)行一個消息環(huán)回測試旱爆。
- PATCH:PATCH方法用于對資源應用部分修改。
請求頭
請求頭包含多組由:
分隔的鍵值對窘茁,用來告訴服務器一些與請求相關的信息怀伦。常用頭信息后邊有寫。
請求體
請求體同請求一起發(fā)送到服務器端山林,一般用來更新數(shù)據(jù)空镜,常用在POST請求,而GET捌朴、OPTIONS親請求一般用來獲取數(shù)據(jù)吴攒,不需要發(fā)送請求體。
請求體分為兩種:
- Single-resource bodies:由單個文件組成砂蔽,該類型body通過Content-Type和Content-Length來定義洼怔,如json數(shù)據(jù),
Content-Type:application/json
左驾,如下:POST /GAIA_FB/Account/Logon HTTP/1.1 Host: testsite.com Connection: keep-alive Content-Length: 144 Accept: application/json, text/javascript, */*; q=0.01 Origin: http://www.testsite.com X-Requested-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Content-Type: application/json Referer: http://testsite.com/Account/logon Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: CULTURE_CODE=zh-CN; loginfrom=aVgy0ql016TDtCp8QAsi0Q== { account: "rascalquan", cultureCode: "zh-CN", password: "112233", returnUrl: "" }
- Multiple-resource bodies:由多部分 body 組成镣隶,每一部分包含不同的信息位。通常是和HTML Forms連系在一起诡右,如附件上傳時安岂,如下,
Content-Type:multipart/form-data
:POST /GAIA_FB/file/upload HTTP/1.1 Host: testsite.com Connection: keep-alive Content-Length: 32159 Origin: http://www.testsite.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryI93ysNPTg7vxds7O Accept: */* Referer: http://www.testsite.com/fileUpload Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: CULTURE_CODE=zh-CN; loginfrom=aVgy0ql016TDtCp8QAsi0Q==; ------WebKitFormBoundaryI93ysNPTg7vxds7O Content-Disposition: form-data; name="prop1" UsbkeyImport.xls ------WebKitFormBoundaryI93ysNPTg7vxds7O Content-Disposition: form-data; name="file"; filename="UsbkeyImport.xls" Content-Type: application/vnd.ms-excel ------WebKitFormBoundaryI93ysNPTg7vxds7O--
HTTP響應報文
HTTP響應報文包括狀態(tài)行帆吻、響應頭掖棉、空行和響應報文體四部分組成,空行用來隔開響應頭與響應報文體剪决,如下圖:
狀態(tài)行
狀態(tài)行由協(xié)議版本、響應碼败许、響應狀態(tài)描述組成。
狀態(tài)碼
響應頭
響應頭與請求頭類似淑蔚,包含多組由:
分隔的鍵值對市殷,用來描述服務器的一些相關的信息。
響應報文體
響應報文體即響應的主體刹衫,如HTML頁面醋寝、JPEG圖片、PDF文件等等带迟,瀏覽器會根據(jù)響應頭中的Content-Type設置的MIME選擇相應的處理方式甥桂,是該呈現(xiàn)還是下載附件。
常用Header
各Header按照用途可以分為請求頭(只用在請求時)邮旷、響應頭(只用在響應時)黄选、通用頭(請求和響應時都可使用)三種。有些可在代碼里修改婶肩,有些不可修改办陷,由用戶代理自行維護,如Date頭律歼。
- Accept:表示客戶端可以接受或處理的MIME類型民镜,服務端從多項類型中選擇一項并以Content-Type回應。
基本語法:<MIME_type>/<MIME_subtype>[;q=權重]
险毁。
其中q代表權重制圈,表示優(yōu)先級,多個類型之間用,
隔開畔况。
<MIME_type>/*
或*/*
代表任意子類型或任意類型鲸鹦。
示例:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 - Accept-Charset:表示客戶端可以接受或處理的字符集類型,服務端從多項類型中選擇一項并以Content-Type回應跷跪。
基本語法:<charset>[;q=權重]
馋嗜,字符集如utf-8或iso-8859-15等。
其中q代表權重吵瞻,表示優(yōu)先級葛菇,多個類型之間用,
隔開橡羞。
不過眯停,一般瀏覽器不會也不用提供,以各類型的默認值即可卿泽。 - Accept-Encoding:表示客戶端可以接受或處理的壓縮編碼類型莺债。
- Accept-Language:表示客戶端可以接受的自然語言。
- Connection:表示當前事務完成后是否關閉連接。
用法:
Connection:Keep-Alive
//保持連接
Connection:Close
//關閉連接 - Content-Disposition:指示響應的內(nèi)容作為內(nèi)聯(lián)形式內(nèi)嵌到頁面中還是附件形式下載到本地九府。
用法:
Content-Disposition:inline
//內(nèi)聯(lián)形式椎瘟,默認
Content-Disposition:attachment;filename="filename1.jpg"
//附件形式覆致,瀏覽器會彈出另存為的提示框侄旬,filename為下載時另存為的文件名
Content-Disposition:form-data;name="field1";filename="filename1.jpg"
//用于類型為multipate body時,多為表單提交煌妈,可看上文中MIME類型的Multipart類型中multipart/form-data
四儡羔、Cookie
概述
HTTP Cookie是服務器發(fā)送到瀏覽器并保存在瀏覽器端的一小塊數(shù)據(jù),它會在瀏覽器下次同一服務器時一并發(fā)送給服務器璧诵。Cookie使無狀態(tài)的HTTP記錄穩(wěn)定的狀態(tài)成為了可能汰蜘。
Cookie作用
- 會話管理:記錄用戶的登錄狀態(tài)、訪問狀態(tài)等之宿,記錄登錄狀態(tài)是cookie最常用的功能族操,通常服務器會在用戶登錄成功后下發(fā)一個sessionid以免去每次登錄。記錄訪問狀態(tài)可以保持用戶的瀏覽記錄比被,如購物車等信息色难。
- 個性設置:記錄用戶一些自定義設置,如將主題等缀、語言等的設置保存在cookie中枷莉。
- 行為追蹤:跟蹤并分析用戶的行為,如Google投放的廣告等尺迂。
使用
創(chuàng)建Cookie
服務器通過在響應頭添加Set-Cookie: <cookie名>=<cookie值>
來告知瀏覽器需要保存cookie笤妙,當瀏覽器看到該響應頭后就會把其中的cookie鍵值對保存下來,并在后續(xù)的請求中自動添加cookie:<cookie名>=<cookie值>
請求頭噪裕。
- 會話期Cookie:像
<cookie名>=<cookie值>
這樣的cookie就是會話期cookie蹲盘,只在這次會話期間生效,當關閉瀏覽器后就會自動刪除膳音。 - 持久性Cookie:通過為cookie設置Expires(特定過期時間)或Max-Age(有效秒數(shù))屬性可以實現(xiàn)cookie的持久化保存辜限。如
Set-Cookie: id=a3fWa; Expires=Thu Nov 22 2018 16:25:27 GMT;
設置cookie id為特定的失效時間2018/11/22 16:25:27。如Set-Cookie: id=a3fWa; Max-Age=1000;
設置cookie id在1000秒后失效严蓖。
訪問Cookie
- HTTP訪問:從Cookie請求頭直接訪問薄嫡。
- Javascript訪問:對于非HttpOnly標記的cookie可以通過document.cookie訪問或修改cookie。
Cookie安全
可以為cookie添加Secure或HttpOnly標記颗胡。
添加了Secure標記的cookie只有在https加密時才會發(fā)送給服務器以保證cookie不會被截取毫深,如Set-Cookie: id=a3fWa;Secure
。盡管如此毒姨,還是不建議將敏感信息哑蔫,如密碼,放在cookie中
添加了HttpOnly標記的cookie只在發(fā)送HTTP消息時才能被發(fā)現(xiàn),而不能被js抓取到闸迷,避免了XSS(跨域腳本攻擊)的危害嵌纲。
Cookie作用域
Domain 和 Path 標識定義了Cookie的作用域:即Cookie應該發(fā)送給哪些URL。
Domain標識了哪些主機可以接收cookie腥沽,如果不指定逮走,則默認只有當前主機(不包含子域名)可以接收該cookie;如果指定了Domain今阳,則一般包括子域名也可接收师溅。
Path標識了哪些路徑(及其子路徑)可以接收該cookie。如Set-Cookie: id=a3fWa;path=\docs
盾舌。
五墓臭、Cache
Cache概述
常用的緩存有數(shù)據(jù)庫緩存、服務器端緩存妖谴、瀏覽器端緩存等窿锉,Cache即瀏覽器端緩存,當瀏覽器請求一個web資源后膝舅,在瀏覽器端保存一份該資源的副本嗡载,當下次再次請求相同資源時,如果滿足特定條件則直接返回該資源的副本铸史,而無需再次發(fā)起請求鼻疮。
合理利用緩存有助于:
- 緩解服務器壓力
- 減少網(wǎng)絡帶寬
- 加快響應速度
Cache三大策略
Cache緩存的工作原理包括三大策略:緩存存儲策略、緩存過期策略琳轿、緩存驗證策略判沟。三大策略分別處理緩存的是否存儲、何時過期崭篡、驗證緩存是否有效挪哄。
緩存存儲策略
與緩存存儲策略相關的有Cache-Control的幾個header和Pragma
- Cache-Control:Private:緩存,只能被單個用戶緩存琉闪,不能作為共享緩存(即代理服務器不能緩存它),可以緩存響應內(nèi)容迹炼。
- Cache-Control:Public:緩存,可以被任何對象(包括:發(fā)送請求的客戶端颠毙,代理服務器斯入,等等)緩存。
- Cache-Control:no-cache:緩存蛀蜜,但強制將請求提交給原始服務器進行驗證刻两。
- Cache-Control:only-if-cached:表明客戶端只接受已緩存的響應,并且不要向原始服務器檢查是否有更新的拷貝滴某。
- Cache-Control:max-age:緩存磅摹,設置緩存存儲的最大周期滋迈,超過這個時間緩存被認為過期(單位秒)。
- Cache-Control:no-store:不緩存户誓。
- Pragma:no-cache:同Cache--Control:no-cache饼灿,強制緩存驗證,上古產(chǎn)物帝美,不建議使用了碍彭。
無法被緩存的情況:
- 響應頭中包含Cache-Control:no-store頭的請求無法被緩存
- 響應頭中包含Cache-Control:max-age=0的請求無法被緩存
- 響應頭中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的請求無法被緩存
- POST請求無法被緩存
緩存過期策略
與緩存過期策略相關的HTTP頭:
- Cache-Control:max-age:緩存存儲的最大周期证舟,優(yōu)先級高于Expires硕旗。
- Expires:即在此時候之后窗骑,緩存過期女责。
緩存過期并不意味著緩存被刪除或失效,即使緩存過期了還是有可能使用的创译。后邊的緩存驗證策略中會講到抵知。
緩存驗證策略
當緩存的文檔過期后,需要進行緩存驗證或者重新獲取資源软族。只有在服務器返回強校驗器或者弱校驗器時才會進行驗證刷喜。
弱校驗器:Last-Modified
響應頭可以作為一種弱校驗器。說它弱是因為它只能精確到一秒立砸。如果響應頭里含有這個信息掖疮,客戶端可以在后續(xù)的請求中帶上 If-Modified-Since:Last-Modified-value
或If-Unmodified-Since:Last-Modified-value
來驗證緩存。
- If-Modified-Since:是否在指定時間之后做了修改颗祝,將上次響應頭中的Last-Modified的值發(fā)給服務器驗證浊闪,如果服務器資源在此之后有做修改,則返回新的資源螺戳,狀態(tài)碼200搁宾,否則返回一個不帶消息主體的304響應,以告訴瀏覽器使用緩存即可倔幼。通常只用在GET盖腿、HEAD請求中。
- If-Unmodified-Since:是否在指定時間之后未做修改损同,類似if-Modified-Since翩腐,不過通常只用于POST請求。如并發(fā)修改時膏燃,未防止覆蓋修改茂卦,如果請求的資源在指定時間之后發(fā)生了修改,則返回412(前提條件失效)錯誤蹄梢,如果未修改疙筹,則做出修改富俄,并返回200。
強校驗器:ETag可以唯一標識一份資源而咆,可以通過特定計算獲得(如md5)霍比,如果響應頭里含有這個信息,客戶端可以在后續(xù)的請求中帶上 If-Match:ETag-value
或If-None-Match:ETag-value
來驗證緩存暴备。盡管ETag比Last-Modified準確很多悠瞬,但是對ETag的計算會消耗一定的服務器資源或客戶端資源。
- If-None-Match:配合ETag使用涯捻,當且僅當服務器上沒有任何資源的 ETag 屬性值與這個首部中列出的相匹配的時候浅妆,服務器端會才返回所請求的資源(GET、HEAD)或?qū)Ψ掌髻Y源做修改(POST障癌、PUT)凌外,響應碼為200 ,否則返回304響應碼(GET、HEAD)或412錯誤(POST涛浙、PUT)康辑。
- If-Match:類似If-None-Match,驗證通過則返回200轿亮,否則返回412疮薇。If-Match與if-None-Match優(yōu)先級高于if-Modified-Since與if-Unmodified-Since。
如圖:
訪問方式
用戶訪問方式可以總結為三種:
- 直接訪問:點擊超鏈接我注、地址欄輸入URL的方式按咒,會進行普通的緩存驗證策略。
- 刷新頁面:點擊刷新按鈕但骨、F5励七、右鍵重新加載,會強制驗證緩存嗽冒,在請求頭中加上
If-Modified-Since
或If-None-Match
呀伙,如果滿足驗證則返回資源,否則返回304來從緩存獲取資源添坊。 - Ctrl+F5:不采取緩存剿另,強制服務器重新發(fā)送完整請求,這時請求頭即沒有
If-Modified-Since
也沒有If-None-Match
贬蛙。
緩存實踐
綜上對各種HTTP緩存控制頭部的對比以及用戶可能出現(xiàn)的瀏覽器刷新行為的討論雨女,當我們在一個項目上做http緩存的應用時,我們實際上還是會把上述提及的大多數(shù)首部字段均使用上阳准。
- Expires / Cache-Control
Expires用時刻來標識失效時間氛堕,不免收到時間同步的影響,而Cache-Control使用時間間隔很好的解決了這個問題野蝇。 但是 Cache-Control 是 HTTP1.1 才有的讼稚,不適用于 HTTP1.0括儒,而 Expires 既適用于 HTTP1.0,也適用于 HTTP1.1锐想,所以說在大多數(shù)情況下同時發(fā)送這兩個頭會是一個更好的選擇帮寻,當客戶端兩種頭都能解析的時候,會優(yōu)先使用 Cache-Control赠摇。 - Last-Modified / ETag
二者都是通過某個標識值來請求資源固逗, 如果服務器端的資源沒有變化,則自動返回 HTTP 304 (Not Changed)狀態(tài)碼藕帜,內(nèi)容為空烫罩,這樣就節(jié)省了傳輸數(shù)據(jù)量。而當資源發(fā)生比那話后洽故,返回和第一次請求時類似贝攒。從而保證不向客戶端重復發(fā)出資源,也保證當服務器有變化時收津,客戶端能夠得到最新的資源饿这。
其中Last-Modified使用文件最后修改作為文件標識值浊伙,它無法處理文件一秒內(nèi)多次修改的情況撞秋,而且只要文件修改了哪怕文件實質(zhì)內(nèi)容沒有修改,也會重新返回資源內(nèi)容嚣鄙;ETag作為“被請求變量的實體值”吻贿,其完全可以解決Last-Modified頭部的問題,但是其計算過程需要耗費服務器資源哑子。 - from-cache / 304
Expires和Cache-Control都有一個問題就是服務端作為的修改舅列,如果還在緩存時效里,那么客戶端是不會去請求服務端資源的(非刷新)卧蜓,這就存在一個資源版本不符的問題帐要,而強制刷新一定會發(fā)起HTTP請求并返回資源內(nèi)容,無論該內(nèi)容在這段時間內(nèi)是否修改過弥奸;而Last-Modified和Etag每次請求資源都會發(fā)起請求榨惠,哪怕是很久都不會有修改的資源,都至少有一次請求響應的消耗盛霎。
對于所有可緩存資源赠橙,指定一個Expires或Cache-Control max-age以及一個Last-Modified或ETag至關重要。同時使用前者和后者可以很好的相互適應愤炸。
前者不需要每次都發(fā)起一次請求來校驗資源時效性期揪,后者保證當資源未出現(xiàn)修改的時候不需要重新發(fā)送該資源。而在用戶的不同刷新頁面行為中规个,二者的結合也能很好的利用HTTP緩存控制特性凤薛,無論是在地址欄輸入URI然后輸入回車進行訪問姓建,還是點擊刷新按鈕,瀏覽器都能充分利用緩存內(nèi)容缤苫,避免進行不必要的請求與數(shù)據(jù)傳輸引瀑。 - 避免304
對于一些css或js等靜態(tài)文件,不會頻繁更新榨馁,但每次更新后又需保證客戶端能獲取到最新憨栽,而不是從緩存中獲取∫沓妫可以在url后添加版本號(?md5
或?version
)的方式模擬服務端ETag的原理屑柔。而每次更新資源后只需更新其版本號即可,同時為其設置一個較長的Expire或max-age珍剑。