本文為《三萬長文50+趣圖帶你領(lǐng)悟web編程的內(nèi)功心法》第三個(gè)章節(jié)。
3、HTTP/1.1報(bào)文詳解
在RFC2616中心詳細(xì)的描述了HTTP/1.1[1]的報(bào)文薇宠,感興趣的朋友也可以前往閱讀阱当。
HTTP是基于TCP的争拐,HTTP作為應(yīng)用層協(xié)議茄茁,會(huì)在TCP/IP協(xié)議棧往下傳遞的時(shí)候鹰祸,不斷封裝數(shù)據(jù)幀仆抵,如下圖:
上面HTTP正文即是以我們HTTP報(bào)文格式來組織的跟继。下面我們看看具體的HTTP報(bào)文的格式。
3.1镣丑、HTTP報(bào)文組成部分
HTTP請求和響應(yīng)都使用如下通用的格式:
-
start-line
:起始行还栓,起始行可以為以下兩者之一:-
Request-Line
:請求行,如:GET /hello-world2.html HTTP/1.1
-
Status-Line
:狀態(tài)行传轰,如:HTTP/1.1 200 OK
-
*(message-header CRLF)
:0個(gè)或者多個(gè)消息頭
剩盒;CRLF
:一個(gè)空行;[message-body]
:可選的消息體;
可以分別把請求報(bào)文和響應(yīng)報(bào)文分開來描述:
請求報(bào)文
響應(yīng)報(bào)文
可以發(fā)現(xiàn)辽聊,請求報(bào)文和響應(yīng)報(bào)文格式就起始行不一樣纪挎。
下面我們逐個(gè)來介紹。
為了盡可能保證內(nèi)容的準(zhǔn)確性跟匆,下面報(bào)文各種字段說明部分內(nèi)容异袄,大部分整理自RFC2616和MDN web docs:
- Hypertext Transfer Protocol -- HTTP/1.1 2616[1]
- HTTP. MDN web docs[2]
- 《HTTP權(quán)威指南》
以上資料內(nèi)容有沖突的,以RFC2616的為準(zhǔn)玛臂。
3.2烤蜕、請求行
請求行格式:
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
3.2.1、Method
方法是區(qū)分大消息的迹冤,以下是常用的方法:
方法 | 說明 |
---|---|
OPTIONS | 列出可以對服務(wù)器資源執(zhí)行哪些方法 |
GET | 獲取資源 |
HEAD | 獲取資源的首部讽营,與GET類似,但是不會(huì)響應(yīng)消息體 |
POST | 向服務(wù)器提交數(shù)據(jù) |
PUT | 將請求主體部分存儲(chǔ)在服務(wù)器上 |
DELETE | 刪除資源 |
TRACE | 對可能經(jīng)過代理服務(wù)器傳送到服務(wù)器上的報(bào)文進(jìn)行追蹤 |
CONNECT | 建立連接隧道 |
extension-method | 擴(kuò)展方法 |
另外泡徙,服務(wù)器還可以實(shí)現(xiàn)一些自己的請求方法橱鹏,這些附加的方法是對HTTP規(guī)范的擴(kuò)展,因此也成為擴(kuò)展方法堪藐。
extension-method = token
請求可能的返回結(jié)果:
-
405:表示請求的方法不被允許莉兰,這個(gè)時(shí)候服務(wù)器響應(yīng)頭會(huì)響應(yīng)當(dāng)前資源允許的方法,如:
Allow: GET, HEAD, PUT
501:代表原服務(wù)器的該方法未能被識別或者未實(shí)現(xiàn)礁竞;
下面逐個(gè)方法介紹下:
GET
GET方法意味著可以檢索 Request-URI標(biāo)識的任何信息糖荒。
如果Request-URI涉及到創(chuàng)建數(shù)據(jù),則應(yīng)該將新建的數(shù)據(jù)作為響應(yīng)實(shí)體返回模捂。
如果請求消息包含 If-Modified-Since寂嘉,If-Unmodified-Since,If-Match枫绅,If-None_match或If-Range標(biāo)頭字段泉孩,則此時(shí)的Get為條件GET。通過使用緩存標(biāo)頭并淋,可以盡可能避免不必要的網(wǎng)絡(luò)傳輸寓搬。
如果請求標(biāo)頭包含Range,則GET方法變?yōu)椴糠諫ET县耽。
HEAD
HEAD方法與GET方法很類似句喷,但是HEAD方法在在響應(yīng)中只返回首部,不會(huì)反悔消息體兔毙。
這就允許客戶端再不用獲取實(shí)際資源的情況下唾琼,對資源首部進(jìn)行檢查。如:
- 檢查資源是否有更新:如果獲取到的 Content-Length澎剥、Content-MD5锡溯、ETag、Last-Modified與之前獲取到的值不同,那么緩存應(yīng)該被視為過期祭饭;
- 查看響應(yīng)狀態(tài)碼芜茵,查看資源是否存在忿薇;
- 獲取首部更多信息泽西,判斷資源情況。
POST
POST方法起初是用來向服務(wù)器傳輸數(shù)據(jù)的癣亚,通常用來提交HTML的表單到服務(wù)器寺鸥。
PUT
PUT方法用于向服務(wù)器寫入資源猪钮,如果Request-URI對應(yīng)的資源已經(jīng)存在的話,就進(jìn)行更新胆建。
注意:
POST用于向服務(wù)器發(fā)送數(shù)據(jù)烤低,PUT用于向服務(wù)器上的資源中存儲(chǔ)數(shù)據(jù)。
DELETE
請求服務(wù)器刪除URL所指示的資源眼坏,但是客戶端無法保證刪除操作一定會(huì)被執(zhí)行拂玻,除非在響應(yīng)式服務(wù)器打算刪除資源或者將其移動(dòng)到無法訪問的位置酸些≡滓耄可能的響應(yīng):
- 如果響應(yīng)包含描述狀態(tài)的實(shí)體,則響應(yīng)200(確定)魄懂;
- 如果尚未執(zhí)行刪除操作沿侈,則響應(yīng)202(接受);
- 如果已執(zhí)行該操作市栗,并且響應(yīng)不包含任何實(shí)體缀拭,則響應(yīng)204(無內(nèi)容)。
此方法的響應(yīng)不可緩存填帽。
TRACE
一個(gè)請求從客戶端到服務(wù)端蛛淋,中間可能會(huì)經(jīng)歷各種代理、網(wǎng)關(guān)等程序篡腌,每個(gè)中間節(jié)點(diǎn)都可能修改原始HTTP請求褐荷。為此,通過TRACE嘹悼,服務(wù)端會(huì)在接收到請求后反饋一個(gè)TRACE響應(yīng)叛甫,并且在響應(yīng)主體中攜帶它收到的原始請求報(bào)文⊙罨铮客戶端拿到TRACE響應(yīng)其监,就可以進(jìn)行測試和診斷了。其中Via標(biāo)頭字段特別有用限匣,它用于充當(dāng)請求鏈的跟蹤抖苦。
可以使用Max-Forwards標(biāo)頭字段限制請求鏈的長度,這對于測試無限循環(huán)中轉(zhuǎn)發(fā)消息的代理很有用。
如果請求有效睛约,則響應(yīng)應(yīng)該在實(shí)體正文中包含整個(gè)請求消息鼎俘,其 Content-Type為"message/http"。對此方法的響應(yīng)絕對不能緩存辩涝。
TRACE允跨站點(diǎn)跟蹤問題贸伐,并且可能使黑客可以選擇竊取您的cookie信息≌基于安全的考慮捉邢,一般的服務(wù)器會(huì)關(guān)掉TRACE:
TraceEnable off
這樣執(zhí)行TRACE會(huì)導(dǎo)致客戶端收到一個(gè)405不允許使用方法的狀態(tài)碼。
CONNECT
CONNECT 方法可以開啟一個(gè)客戶端與所請求資源之間的雙向溝通的通道商膊。它可以用來創(chuàng)建隧道(tunnel)伏伐。
例如,CONNECT
可以用來訪問采用了 SSL (HTTPS) 協(xié)議的站點(diǎn)晕拆∶牯幔客戶端要求代理服務(wù)器將 TCP 連接作為通往目的主機(jī)隧道。之后該服務(wù)器會(huì)代替客戶端與目的主機(jī)建立連接实幕。連接建立好之后吝镣,代理服務(wù)器會(huì)面向客戶端發(fā)送或接收 TCP 消息流。[3]
OPTIONS
通過該方法昆庇,可以請求服務(wù)器獲取Request-URI對應(yīng)支持的各種通信選項(xiàng)的信息末贾。最常見的如:詢問服務(wù)器當(dāng)前URI支持哪些請求方法。
此方法響應(yīng)不能緩存整吆。
方法的安全性與冪等性
所謂安全性拱撵,就是無論方法執(zhí)行多少次,服務(wù)器上的數(shù)據(jù)都不會(huì)被改變表蝙。
安全方法
:GET拴测、HEAD;
不安全方法
:POST府蛇、PUT集索、DELETE操作則會(huì)改動(dòng)數(shù)據(jù)。
所謂冪等欲诺,就是多次執(zhí)行一個(gè)方法抄谐,結(jié)果都是相同的。
冪等方法
:GET扰法、HEAD蛹含、PUT、DELETE塞颁;
非冪等方法
:POST浦箱。
3.2.2吸耿、Request-URI
URI,Uniform Resource Identifier酷窥,請求的統(tǒng)一資源標(biāo)識符咽安。
3.2.2.1、URI與URL什么關(guān)系蓬推?
我們經(jīng)常會(huì)用到這兩個(gè)概念妆棒,但是他們是什么意思呢?
URI沸伏,Uniform Resource Identifier糕珊,統(tǒng)一資源標(biāo)識符,能夠唯一的標(biāo)識網(wǎng)上的一個(gè)資源毅糟,比如红选,我的網(wǎng)站IT宅的Logo:
https://www.itzhai.com/resources/images/itzhai_logo_home_page.jpg
只要在世界的任何一個(gè)有網(wǎng)絡(luò)的地方,發(fā)起請求姆另,就可以拿到這個(gè)圖片喇肋,這個(gè)URI具有唯一性。那什么是URL呢迹辐?
URI有兩種形式:URL和URN蝶防。
URL
URL,Uniform Resource Locator右核,統(tǒng)一資源定位符慧脱,描述了一臺(tái)特定服務(wù)器上某個(gè)資源的特定位置渺绒。例如上面的鏈接就是一個(gè)統(tǒng)一資源定位符:
-
secheme方案
:指定方位資源所使用的協(xié)議類型贺喝,如HTTPS; -
主機(jī)與端口
:英特網(wǎng)地址宗兼,即域名躏鱼,這里默認(rèn)為80端口; -
路徑
:其余部分指定web服務(wù)器上的某個(gè)資源殷绍。
幾乎所有的 URI都是URL染苛。
一個(gè)完整的URL格式如下:
-
用戶名和密碼
:有寫服務(wù)器要求輸入用戶名和密碼才允許用戶訪問數(shù)據(jù),如FTP主到; -
?query 查詢字符串
:可以通過查詢字符串進(jìn)行查詢來縮小所請求資源類型的范圍茶行; -
fragment片段
:指向HTML文檔中特定的圖片或者小節(jié)。
URN
URL登钥,Uniform Resource Name畔师,統(tǒng)一資源名,作為特定內(nèi)容的唯一名稱牧牢,與資源所在位置無關(guān)看锉。也就是說姿锭,我可以給一份文檔定義一個(gè)URN,不管你把這個(gè)文檔放到哪里伯铣,有多少個(gè)URL呻此,但是都只有唯一個(gè)URN。舉個(gè)例子腔寡,因特網(wǎng)標(biāo)準(zhǔn)文檔 RFC 3986不管存在哪個(gè)服務(wù)器上焚鲜,都可以用唯一的URN來命名:
urn:ietf:rfc:3986
URN處于試驗(yàn)階段,暫未大范圍使用放前。
再通俗易懂點(diǎn)來說:URN就相當(dāng)于身份證恃泪,通過特定的規(guī)則,制定了一串唯一的字符串作為你的身份證犀斋,但是沒有規(guī)定身份證一定要放在哪里贝乎,只是作為你的個(gè)人唯一憑證。URL相當(dāng)于是快遞單上的地址叽粹,根據(jù)地址览效,快遞員一定可以把快遞送到唯一的一個(gè)目的地。
3.2.3虫几、HTTP-Version
指定了當(dāng)前請求用到的HTTP協(xié)議版本锤灿。
3.3、消息頭[4]
通過傳遞消息頭(首部)辆脸,服務(wù)器和客戶端可以把自己的信息或者是請求響應(yīng)相關(guān)信息進(jìn)行傳遞但校。
可以把首部分為:通用首部,請求首部啡氢,響應(yīng)首部状囱,實(shí)體首部,擴(kuò)展首部倘是。下面就來詳細(xì)介紹下亭枷。
3.3.1、通用首部
有些首部搀崭,不管是請求還是響應(yīng)都會(huì)出現(xiàn)他們的身影叨粘,我們把他們歸類為通用首部。常見通用首部如下表格所示:
首部 | 說明 |
---|---|
Cache-Control | 通過指定指令來實(shí)現(xiàn)緩存機(jī)制 |
Connection | Connection 頭(header) 決定當(dāng)前的事務(wù)完成后瘤睹,是否會(huì)關(guān)閉網(wǎng)絡(luò)連接升敲。如果該值是“keep-alive”,網(wǎng)絡(luò)連接就是持久的轰传,不會(huì)關(guān)閉驴党,使得對同一個(gè)服務(wù)器的請求可以繼續(xù)在該連接上完成:<br />Connection: keep-alive <br />Connection: close |
Data | 提供報(bào)文創(chuàng)建的時(shí)間 |
MIME-Version | 提供發(fā)送端使用的MIME版本 |
Trailer | 允許發(fā)送方在分塊發(fā)送的消息后面添加額外的元信息,這些元信息可能是隨著消息主體的發(fā)送動(dòng)態(tài)生成的绸吸,比如消息的完整性校驗(yàn)鼻弧,消息的數(shù)字簽名设江,或者消息經(jīng)過處理之后的最終狀態(tài)等。 |
Transfer-Encoding | 告知接收端報(bào)文的編碼方式 |
Upgrade | 允許客戶端指定它支持并且希望使用的通信協(xié)議攘轩,如果服務(wù)器認(rèn)為適合叉存,則切換協(xié)議,服務(wù)器必須使用101(交換協(xié)議)中的Upgrade標(biāo)頭字段響應(yīng)度帮,以知識正在交換的協(xié)議歼捏。 |
Via | 顯示報(bào)文經(jīng)過的中間節(jié)點(diǎn),用來追蹤消息轉(zhuǎn)發(fā)情況笨篷,防止循環(huán)請求瞳秽,以及識別在請求或響應(yīng)傳遞鏈中消息發(fā)送者對于協(xié)議的支持能力 |
Warning | 包含報(bào)文當(dāng)前狀態(tài)可能存在的問題。在響應(yīng)中可以出現(xiàn)多個(gè) Warning 首部率翅。一般來說练俐, Warning 首部可以應(yīng)用于任何類型的報(bào)文。然而一部分警告碼(warn-code)是為緩存代理服務(wù)器定制的冕臭,并且只可以應(yīng)用在響應(yīng)報(bào)文中腺晾。 |
3.3.2、請求首部
客戶端通過傳遞請求頭字段辜贵,將有關(guān)請求以及有關(guān)客戶端本身的其他信息傳遞給服務(wù)器悯蝉,這些字段充當(dāng)請求修飾符,其語義等同于編程語言方法調(diào)用中的參數(shù)托慨。
常見的請求頭如下:
Accept首部
首部 | 說明 |
---|---|
Accept | 表明客戶端能夠接受的媒體類型 |
Accept-Charset | 表明客戶端能夠接受的字符集 |
Accept-Encoding | 表明客戶端能夠接受的編碼方式 |
Accept-Language | Section 14.4 |
TE | 表明客戶端能夠接受的擴(kuò)展傳輸編碼 |
條件請求首部
首部 | 說明 |
---|---|
Expect | 指示客戶端要求特定的服務(wù)器行為<br />目前規(guī)范中只規(guī)定了 "100-continue" 這一個(gè)期望條件:通知接收方客戶端要發(fā)送一個(gè)體積可能很大的消息體鼻由,期望收到狀態(tài)碼為100 (Continue) 的臨時(shí)回復(fù) |
If-Match | 請求首部 If-Match 的使用表示這是一個(gè)條件請求。在請求方法為 GET 和 HEAD 的情況下厚棵,服務(wù)器僅在請求的資源滿足此首部列出的 ETag 值時(shí)才會(huì)返回資源蕉世。而對于 PUT 或其他非安全方法來說,只有在滿足條件的情況下才可以將資源上傳窟感。 |
If-Modified-Since |
If-Modified-Since 是一個(gè)條件式請求首部讨彼,服務(wù)器只在所請求的資源在給定的日期時(shí)間之后對內(nèi)容進(jìn)行過修改的情況下才會(huì)將資源返回歉井,狀態(tài)碼為 200 柿祈。如果請求的資源從那時(shí)起未經(jīng)修改,那么返回一個(gè)不帶有消息主體的 304 響應(yīng)哩至,而在 Last-Modified 首部中會(huì)帶有上次修改時(shí)間躏嚎。 不同于 If-Unmodified-Since , If-Modified-Since 只可以用在GET 或 HEAD 請求中。 |
If-None-Match | 對于 GET 和 HEAD 請求方法來說菩貌,當(dāng)且僅當(dāng)服務(wù)器上沒有任何資源的 ETag 屬性值與這個(gè)首部中列出的相匹配的時(shí)候卢佣,服務(wù)器端會(huì)才返回所請求的資源,響應(yīng)碼為 200 箭阶。對于其他方法來說虚茶,當(dāng)且僅當(dāng)最終確認(rèn)沒有已存在的資源的 ETag 屬性值與這個(gè)首部中所列出的相匹配的時(shí)候戈鲁,才會(huì)對請求進(jìn)行相應(yīng)的處理。 |
If-Range |
If-Range HTTP 請求頭字段用來使得 Range 頭字段在一定條件下起作用:當(dāng)字段值中的條件得到滿足時(shí)嘹叫,Range 頭字段才會(huì)起作用婆殿,同時(shí)服務(wù)器回復(fù)206 部分內(nèi)容狀態(tài)碼,以及Range 頭字段請求的相應(yīng)部分罩扇;如果字段值中的條件沒有得到滿足婆芦,服務(wù)器將會(huì)返回 200 OK 狀態(tài)碼,并返回完整的請求資源喂饥。 |
If-Unmodified-Since | HTTP協(xié)議中的 If-Unmodified-Since 消息頭用于請求之中消约,使得當(dāng)前請求成為條件式請求:只有當(dāng)資源在指定的時(shí)間之后沒有進(jìn)行過修改的情況下,服務(wù)器才會(huì)返回請求的資源员帮,或是接受 POST 或其他 non-safe 方法的請求或粮。如果所請求的資源在指定的時(shí)間之后發(fā)生了修改,那么會(huì)返回 412 (Precondition Failed) 錯(cuò)誤捞高。 |
Range | The Range 是一個(gè)請求首部被啼,告知服務(wù)器返回文件的哪一部分。在一個(gè) Range 首部中棠枉,可以一次性請求多個(gè)部分浓体,服務(wù)器會(huì)以 multipart 文件的形式將其返回。如果服務(wù)器返回的是范圍響應(yīng)辈讶,需要使用 206 Partial Content 狀態(tài)碼命浴。假如所請求的范圍不合法,那么服務(wù)器會(huì)返回 416 Range Not Satisfiable 狀態(tài)碼贱除,表示客戶端錯(cuò)誤生闲。服務(wù)器允許忽略 Range 首部,從而返回整個(gè)文件月幌,狀態(tài)碼用 200 碍讯。 |
安全請求首部
首部 | 說明 |
---|---|
Authorization | HTTP協(xié)議中的 Authorization 請求消息頭含有服務(wù)器用于驗(yàn)證用戶代理身份的憑證,通常會(huì)在服務(wù)器返回401 Unauthorized 狀態(tài)碼以及WWW-Authenticate 消息頭之后在后續(xù)請求中發(fā)送此消息頭扯躺。 |
Cookie |
Cookie 是一個(gè)請求首部捉兴,其中含有先前由服務(wù)器通過 Set-Cookie 首部投放并存儲(chǔ)到客戶端的 HTTP cookies。 |
Cookie2 | 這個(gè)已經(jīng)被廢棄的 Cookie2 請求首部曾經(jīng)被用來告知瀏覽器該用戶代理支持“新型” cookies录语,但是現(xiàn)代的用戶代理一般使用 Cookie 來替代 Cookie2倍啥。
|
代理請求首部
首部 | 說明 |
---|---|
Max-Forwards | 在通往源端服務(wù)器的路徑上,將請求轉(zhuǎn)發(fā)給其他代理或者網(wǎng)關(guān)的最大次數(shù)澎埠,與TRACE方法類似虽缕。 |
Proxy-Authorization |
Proxy-Authorization 是一個(gè)請求首部,其中包含了用戶代理提供給代理服務(wù)器的用于身份驗(yàn)證的憑證蒲稳。這個(gè)首部通常是在服務(wù)器返回了 407 Proxy Authentication Required 響應(yīng)狀態(tài)碼及 Proxy-Authenticate 首部后發(fā)送的氮趋。 |
Proxy-Connection | 同Connection伍派,不過這個(gè)首部是在與代理建立連接時(shí)使用。 |
3.3.3剩胁、響應(yīng)首部
首部 | 說明 |
---|---|
Age |
Age 消息頭里包含對象在緩存代理中存貯的時(shí)長拙已,以秒為單位。<br />Age的值通常接近于0摧冀。表示此對象剛剛從原始服務(wù)器獲取不久倍踪;其他的值則是表示代理服務(wù)器當(dāng)前的系統(tǒng)時(shí)間與此應(yīng)答中的通用頭 Date 的值之差。 |
Retry-After | 在HTTP協(xié)議中索昂,響應(yīng)首部 Retry-After 表示用戶代理需要等待多長時(shí)間之后才能繼續(xù)發(fā)送請求建车。這個(gè)首部主要應(yīng)用于以下兩種場景:<br />- 當(dāng)與 503 響應(yīng)一起發(fā)送的時(shí)候,表示服務(wù)下線的預(yù)期時(shí)長椒惨;<br />- 當(dāng)與重定向響應(yīng)一起發(fā)送的時(shí)候缤至,比如 301 (Moved Permanently,永久遷移)康谆,表示用戶代理在發(fā)送重定向請求之前需要等待的最短時(shí)間领斥。 |
Server |
Server 首部包含了處理請求的源頭服務(wù)器所用到的軟件相關(guān)信息。<br />避免描述的過于詳細(xì)沃暗,因?yàn)檫@有可能泄露服務(wù)器內(nèi)部實(shí)現(xiàn)細(xì)節(jié)月洛,或者被攻擊者找到已知安全漏洞。 |
Title | 對于HTML文檔來說孽锥,就是HTML文案定的源端給出的標(biāo)題嚼黔。<br />該首部定義與原始的 HTTP/1.0草案,并未列入RFC2616惜辑。 |
Warning |
Warning 是一個(gè)通用報(bào)文首部唬涧,包含報(bào)文當(dāng)前狀態(tài)可能存在的問題。在響應(yīng)中可以出現(xiàn)多個(gè) Warning 首部盛撑。<br />一般來說碎节, Warning 首部可以應(yīng)用于任何類型的報(bào)文。然而一部分警告碼(warn-code)是為緩存代理服務(wù)器定制的抵卫,并且只可以應(yīng)用在響應(yīng)報(bào)文中狮荔。格式:<br />Warning: <warn-code> <warn-agent> <warn-text> [<warn-date>]
|
協(xié)商首部
如果資源有多種表示方法,服務(wù)器可以通過協(xié)商首部來傳遞可協(xié)商資源有關(guān)的信息陌僵。
首部 | 說明 |
---|---|
Accept-Range | 服務(wù)器使用 HTTP 響應(yīng)頭 **Accept-Ranges** 標(biāo)識自身支持范圍請求(partial requests)轴合。字段的具體值用于定義范圍請求的單位。<br />當(dāng)瀏覽器發(fā)現(xiàn)Accept-Ranges 頭時(shí)碗短,可以嘗試繼續(xù)中斷了的下載,而不是重新開始题涨。 |
Vary |
Vary 是一個(gè)HTTP響應(yīng)頭部信息偎谁,它決定了對于未來的一個(gè)請求頭总滩,應(yīng)該用一個(gè)緩存的回復(fù)(response)還是向源服務(wù)器請求一個(gè)新的回復(fù)。<br />例如巡雨,移動(dòng)端和桌面端響應(yīng)內(nèi)容是不同的闰渔,為了防止移動(dòng)端誤用了桌面端的緩存,可以這樣指定Vary:Vary: User-Agent
|
安全響應(yīng)首部
首部 | 描述 |
---|---|
Proxy-Authenticate | 指定了獲取 proxy server (代理服務(wù)器)上的資源訪問權(quán)限而采用的身份驗(yàn)證方式铐望。代理服務(wù)器對請求進(jìn)行驗(yàn)證冈涧,以便它進(jìn)一步傳遞請求。<br />Proxy-Authenticate 首部需要與 407 Proxy Authentication Required 響應(yīng)一起發(fā)送正蛙。 |
Set-Cookie | 響應(yīng)首部 Set-Cookie 被用來由服務(wù)器端向客戶端發(fā)送 cookie督弓。 |
Set-Cookie2 | 已廢棄使用。它被服務(wù)器用來向客戶端發(fā)送 cookie 數(shù)據(jù)乒验,但是已經(jīng)在協(xié)議中被標(biāo)記為不贊成使用了愚隧。請使用 Set-Cookie 將其代替。 |
WWW-Authenticate | 定義了使用何種驗(yàn)證方式去獲取對資源的連接锻全。<br />WWW-Authenticate header通常會(huì)和一個(gè) 401 Unauthorized 的響應(yīng)一同被發(fā)送狂塘。 |
3.3.4、實(shí)體首部
用來描述HTTP報(bào)文中實(shí)體相關(guān)信息的首部鳄厌,我們成為實(shí)體首部荞胡。
首部 | 描述 |
---|---|
Allow |
Allow 首部字段用于枚舉資源所支持的 HTTP 方法的集合。 |
Location |
Location 首部指定的是需要將頁面重新定向至的地址了嚎。一般在響應(yīng)碼為3xx的響應(yīng)中才會(huì)有意義:<br />- 303 (See Also) 始終引致請求使用 GET 方法硝训,而,而 307 (Temporary Redirect) 和 308 (Permanent Redirect) 則不轉(zhuǎn)變初始請求中的所使用的方法新思;<br />- 301 (Permanent Redirect) 和 302 (Found) 在大多數(shù)情況下不會(huì)轉(zhuǎn)變初始請求中的方法窖梁,不過一些比較早的用戶代理可能會(huì)引發(fā)方法的變更;<br />除了重定向響應(yīng)之外夹囚, 狀態(tài)碼為 201 (Created) 的消息也會(huì)帶有Location首部纵刘。它指向的是新創(chuàng)建的資源的地址。 |
內(nèi)容首部
首部 | 描述 |
---|---|
Content-Encoding |
Content-Encoding 是一個(gè)實(shí)體消息首部荸哟,用于對特定媒體類型的數(shù)據(jù)進(jìn)行壓縮假哎。 |
Content-Languate |
Content-Language 用來說明訪問者希望采用的語言或語言組合,這樣的話用戶就可以根據(jù)自己偏好的語言來定制不同的內(nèi)容鞍历。 |
Content-Length | 指明發(fā)送給接收方的消息主體的大小舵抹,即用十進(jìn)制數(shù)字表示的八位元組的數(shù)目。 |
Content-Location | 指定的是要返回的數(shù)據(jù)的地址選項(xiàng)劣砍。最主要的用途是用來指定要訪問的資源經(jīng)過內(nèi)容協(xié)商后的結(jié)果的URL惧蛹。 |
Content-MD5 | 消息主題的MD5校驗(yàn)和 |
Content-Range | 描述一個(gè)數(shù)據(jù)片段在整個(gè)文件中的位置 |
Content-Type | 指示資源的MIME類型 media type |
實(shí)體緩存首部
實(shí)體緩存首部提供與被緩存實(shí)體有關(guān)的信息,如什么時(shí)候或者如何緩存,緩存是否有效等香嗓,通過緩存首部可以估計(jì)緩存何時(shí)失效迅腔。
首部 | 描述 |
---|---|
ETag | 資源的特定版本的標(biāo)識符。這可以讓緩存更高效靠娱,并節(jié)省帶寬沧烈,因?yàn)槿绻麅?nèi)容沒有改變,Web服務(wù)器不需要發(fā)送完整的響應(yīng)像云。<br />如果給定URL中的資源更改锌雀,則一定要生成新的Etag值。 |
Expires | 該首部包含日期/時(shí)間迅诬, 即在此時(shí)候之后腋逆,響應(yīng)過期。<br />無效的日期百框,比如 0, 代表著過去的日期闲礼,即該資源已經(jīng)過期。 |
Last-Modified | 含源頭服務(wù)器認(rèn)定的資源做出修改的日期及時(shí)間铐维。 它通常被用作一個(gè)驗(yàn)證器來判斷接收到的或者存儲(chǔ)的資源是否彼此一致柬泽。<br />由于精確度比 ETag 要低,所以這是一個(gè)備用機(jī)制嫁蛇。包含有 If-Modified-Since 或 If-Unmodified-Since 首部的條件請求會(huì)使用這個(gè)字段锨并。 |
3.4、消息體
3.4.1睬棚、請求消息體
并不是所有的請求都需要body第煮,如:GET,HEAD抑党,DELETE包警,OPTIONS通產(chǎn)不需要body。
請求body可以分為兩類:
- Single-resource bodies底靠,由單個(gè)文件組成害晦。該類型 body 由兩個(gè) header 定義:
Content-Type
和Content-Length
; - Multiple-resource bodies暑中,由多部分body組成壹瘟,每一部分包含不同的信息位。通常是和 HTML Forms 連系在一起鳄逾。
3.4.2稻轨、響應(yīng)消息體
并不是所有的響應(yīng)都有body,如 201
或 204
狀態(tài)碼的響應(yīng)一般不會(huì)有body雕凹。
響應(yīng)body可以分為三類:
- Single-resource bodies殴俱,由已知長度的單個(gè)文件組成政冻。該類型 body 由兩個(gè) header 定義:
Content-Type
和Content-Length
; - Single-resource bodies粱挡,由未知長度的單個(gè)文件組成赠幕,通過將
Transfer-Encoding
設(shè)置為chunked
來使用 chunks 編碼俄精; - Multiple-resource bodies询筏,由多部分 body 組成,每部分包含不同的信息段竖慧。但這是比較少見的嫌套。
3.5、狀態(tài)行
響應(yīng)消息的第一行是狀態(tài)行圾旨,由協(xié)議版本踱讨,數(shù)字狀態(tài)代碼及其關(guān)聯(lián)的文本短語組成,每個(gè)元素由SP字符分隔砍的。 除最后的CRLF序列外痹筛,不允許CR或LF。
狀態(tài)行格式:
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
3.5.1廓鞠、Status-Code狀態(tài)碼和Reason-Phrase狀態(tài)描述
狀態(tài)碼是3位數(shù)的整數(shù)結(jié)果代碼帚稠。
狀態(tài)碼的第一位數(shù)字定義響應(yīng)的類別。 后兩位數(shù)字沒有任何分類作用床佳∽淘纾可以分為5個(gè)類別:
- 1xx:信息狀態(tài)碼,收到請求砌们,繼續(xù)進(jìn)行杆麸;
- 2xx:請求成功接收;
- 3xx:重定向浪感,必須采取進(jìn)一步措施才能完成請求昔头;
- 4xx:客戶端錯(cuò)誤,請求包含錯(cuò)誤語法影兽,或者不能被完成揭斧;
- 5xx:服務(wù)器錯(cuò)誤,服務(wù)器無法完成看似有效的請求赢笨;
RFC中定義的狀態(tài)碼很多未蝌,這里我們列出最常見的一些狀態(tài)碼:
狀態(tài)碼 | 描述 | 詳細(xì)說明 |
---|---|---|
101 | Switching Protocol | 該代碼是響應(yīng)客戶端的 Upgrade 標(biāo)頭發(fā)送的,并且指示服務(wù)器也正在切換的協(xié)議茧妒。 |
200 | OK | 請求成功萧吠。 |
204 | No Content | 服務(wù)器成功處理了請求,但不需要返回任何實(shí)體內(nèi)容桐筏,并且希望返回更新了的元信息纸型。<br />用這個(gè)狀態(tài)碼區(qū)分成功狀態(tài)下又返回內(nèi)容和沒返回內(nèi)容的響應(yīng)。 |
206 | Partial Content | 服務(wù)器已經(jīng)成功處理了部分 GET 請求。通過HTTP的分塊下載狰腌,獲取資源的部分時(shí)返回除破。該請求必須包含 Range 頭信息來指示客戶端希望得到的內(nèi)容范圍,并且可能包含 If-Range 來作為請求條件琼腔。<br />206狀態(tài)碼通常會(huì)攜帶Content-Range 瑰枫,用于表示報(bào)文里面body數(shù)據(jù)的具體范圍。 |
301 | Moved Permanently | 永久重定向丹莲,將來任何對此資源的引用都應(yīng)該使用本響應(yīng)返回的若干個(gè) URI 之一光坝。 |
302 | Found | 臨時(shí)重定向,客戶端下次應(yīng)當(dāng)繼續(xù)向原有地址發(fā)送以后的請求甥材。只有在Cache-Control或Expires中進(jìn)行了指定的情況下盯另,這個(gè)響應(yīng)才是可緩存的。 |
304 | Not Modified | 如果客戶端發(fā)送了一個(gè)帶條件的 GET 請求且該請求已被允許洲赵,而文檔的內(nèi)容(自上次訪問以來或者根據(jù)請求的條件)并沒有改變鸳惯,則服務(wù)器應(yīng)當(dāng)返回這個(gè)狀態(tài)碼。304 響應(yīng)禁止包含消息體叠萍,因此始終以消息頭后的第一個(gè)空行結(jié)尾芝发。 |
400 | Bad Request | 語義有誤,當(dāng)前請求無法被服務(wù)器理解俭令。除非進(jìn)行修改后德,否則客戶端不應(yīng)該重復(fù)提交這個(gè)請求。 |
401 | Unauthorized | 當(dāng)前請求需要用戶驗(yàn)證抄腔。該響應(yīng)必須包含一個(gè)適用于被請求資源的 WWW-Authenticate 信息頭用以詢問用戶信息瓢湃。客戶端可以重復(fù)提交一個(gè)包含恰當(dāng)?shù)?Authorization 頭信息的請求赫蛇。 |
403 | Forbidden | 服務(wù)器已經(jīng)理解請求拂封,但是拒絕執(zhí)行它拧额。如果這不是一個(gè) HEAD 請求,而且服務(wù)器希望能夠講清楚為何請求不能被執(zhí)行,那么就應(yīng)該在實(shí)體內(nèi)描述拒絕的原因入撒。當(dāng)然服務(wù)器也可以返回一個(gè) 404 響應(yīng)轻黑,假如它不希望讓客戶端獲得任何信息藐窄。 |
404 | Not Found | 請求失敗遮精,請求所希望得到的資源未被在服務(wù)器上發(fā)現(xiàn)。<br />究竟是不是真的資源不存在呢旺嬉?還得看程序是怎么寫的管行。 |
405 | Method Not Allowed | 請求行中指定的請求方法不能被用于請求相應(yīng)的資源。該響應(yīng)必須返回一個(gè)Allow 頭信息用以表示出當(dāng)前資源能夠接受的請求方法的列表邪媳。 |
408 | Request Timeout | 請求超時(shí)捐顷〉聪荩客戶端沒有在服務(wù)器預(yù)備等待的時(shí)間內(nèi)完成一個(gè)請求的發(fā)送⊙镐蹋客戶端可以隨時(shí)再次提交這一請求而無需進(jìn)行任何更改废赞。 |
409 | Conflict | 由于和被請求的資源的當(dāng)前狀態(tài)之間存在沖突,請求無法完成叮姑。 |
413 | Payload Too Large | 請求提交的實(shí)體數(shù)據(jù)大小超過了服務(wù)器愿意或者能夠處理的范圍唉地。此種情況下,服務(wù)器可以關(guān)閉連接以免客戶端繼續(xù)發(fā)送此請求戏溺。如果這個(gè)狀況是臨時(shí)的渣蜗,服務(wù)器應(yīng)當(dāng)返回一個(gè) Retry-After 的響應(yīng)頭屠尊,以告知客戶端可以在多少時(shí)間以后重新嘗試旷祸。 |
429 | Too Many Requests | 用戶在給定的時(shí)間內(nèi)發(fā)送了太多請求(“限制請求速率”)。 |
431 | Request Header Fields Too Large | 請求頭字段太大( Request Header Fields Too Large) |
500 | Internal Server Error | 服務(wù)器遇到了不知道如何處理的情況讼昆。通常用來捕獲服務(wù)器異常托享,統(tǒng)一返回500,避免輸出詳細(xì)錯(cuò)誤堆棧給別人利用浸赫。 |
501 | Not Implemented | 此請求方法不被服務(wù)器支持且無法被處理闰围。只有GET 和HEAD 是要求服務(wù)器支持的,它們必定不會(huì)返回此錯(cuò)誤代碼既峡。
|
502 | Bad Gateway | 此錯(cuò)誤響應(yīng)表明服務(wù)器作為網(wǎng)關(guān)需要得到一個(gè)處理這個(gè)請求的響應(yīng)羡榴,但是得到一個(gè)錯(cuò)誤的響應(yīng)。 |
503 | Service Unavailable | 服務(wù)器沒有準(zhǔn)備好處理請求运敢。 常見原因是服務(wù)器因維護(hù)或重載而停機(jī)校仑。 |
504 | Gateway Timeout | 當(dāng)服務(wù)器作為網(wǎng)關(guān),不能及時(shí)得到響應(yīng)時(shí)返回此錯(cuò)誤代碼传惠。 |
更多狀態(tài)碼說明:
上面我們把HTTP報(bào)文介紹了一遍迄沫,HTTP作為一個(gè)協(xié)議,只是規(guī)定了大家要遵循這樣的約定卦方,但是具體實(shí)現(xiàn)的時(shí)候羊瘩,還是要看應(yīng)用程序的兼容程度。我們在寫程序的時(shí)候盼砍,也不要跟協(xié)議對著干尘吗,這會(huì)讓對接的同事無法理解的。
你都知道以下狀態(tài)碼的含義了嗎浇坐?
200 204 206 301 302 304 401 403 405 500 501 502 503 504
本文首次發(fā)表于: HTTP/1.1報(bào)文詳解 以及公眾號 Java架構(gòu)雜談睬捶,未經(jīng)許可,不得轉(zhuǎn)載吗跋。
本文為arthinking基于相關(guān)技術(shù)資料和官方文檔撰寫而成侧戴,確保內(nèi)容的準(zhǔn)確性宁昭,如果你發(fā)現(xiàn)了有何錯(cuò)漏之處,煩請高抬貴手幫忙指正酗宋,萬分感激积仗。
如果您覺得讀完本文有所收獲的話,可以關(guān)注我的賬號蜕猫,或者點(diǎn)贊吧寂曹,碼字不易,您的支持就是我寫作的最大動(dòng)力回右,再次感謝隆圆!
為了把相關(guān)系列文章收集起來,方便后續(xù)查閱翔烁,這里我創(chuàng)建了一個(gè)Github倉庫渺氧,把發(fā)布的文章按照分類收集起來了,感興趣的朋友可以Star跟進(jìn):
關(guān)注我的博客IT宅(itzhai.com)
或者公眾號Java架構(gòu)雜談
蹬屹,及時(shí)獲取最新的文章侣背。我將持續(xù)更新后端相關(guān)技術(shù),涉及JVM慨默、Java基礎(chǔ)贩耐、架構(gòu)設(shè)計(jì)、網(wǎng)絡(luò)編程厦取、數(shù)據(jù)結(jié)構(gòu)潮太、數(shù)據(jù)庫、算法虾攻、并發(fā)編程铡买、分布式系統(tǒng)等相關(guān)內(nèi)容。
References
- 謝希仁. 計(jì)算機(jī)網(wǎng)絡(luò)(第6版). 電子工業(yè)出版社.
- TCP/IP詳解 卷1:協(xié)議(原書第2版). 機(jī)械工業(yè)出版社.
- UNIX網(wǎng)絡(luò)編程 卷1:套接字聯(lián)網(wǎng)API. 人民郵電出版社
- HTTP權(quán)威指南. 人民郵電出版社
- HTTP/2基礎(chǔ)教程. 人民郵電出版社
- 劉超. 趣談網(wǎng)絡(luò)協(xié)議. 極客時(shí)間
- 羅劍鋒. 透視HTTP協(xié)議. 即可時(shí)間
本文同步發(fā)表于我的博客IT宅(itzhai.com)和公眾號(Java架構(gòu)雜談)
作者:arthinking | 公眾號:Java架構(gòu)雜談
博客鏈接:https://www.itzhai.com/articles/detailed-explanation-of-http-1-1-messages.html
版權(quán)聲明: 版權(quán)歸作者所有台谢,未經(jīng)許可不得轉(zhuǎn)載寻狂,侵權(quán)必究!聯(lián)系作者請加公眾號朋沮。
-
Hypertext Transfer Protocol -- HTTP/1.1 2616. Retrieved from https://tools.ietf.org/html/rfc2616 ? ?
-
HTTP. MDN web docs. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP ?
-
CONNECT. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/CONNECT ?
-
HTTP Headers. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers ?
-
List of HTTP status codes. Retrieved from https://en.wikipedia.org/wiki/List_of_HTTP_status_codes ?
-
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status ?