HTTP/1.1報(bào)文詳解

本文為《三萬長文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ù)幀仆抵,如下圖:

image-20200818221423546

上面HTTP正文即是以我們HTTP報(bào)文格式來組織的跟继。下面我們看看具體的HTTP報(bào)文的格式。

3.1镣丑、HTTP報(bào)文組成部分

HTTP請求和響應(yīng)都使用如下通用的格式:

image-20200819224006001
  • 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)文

image-20200822180651813

響應(yīng)報(bào)文

image-20200822180702049

可以發(fā)現(xiàn)辽聊,請求報(bào)文和響應(yīng)報(bào)文格式就起始行不一樣纪挎。

下面我們逐個(gè)來介紹。

為了盡可能保證內(nèi)容的準(zhǔn)確性跟匆,下面報(bào)文各種字段說明部分內(nèi)容异袄,大部分整理自RFC2616和MDN web docs:

以上資料內(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)一資源定位符:

image-20200813221737724
  • secheme方案:指定方位資源所使用的協(xié)議類型贺喝,如HTTPS;
  • 主機(jī)與端口:英特網(wǎng)地址宗兼,即域名躏鱼,這里默認(rèn)為80端口;
  • 路徑:其余部分指定web服務(wù)器上的某個(gè)資源殷绍。

幾乎所有的 URI都是URL染苛。

一個(gè)完整的URL格式如下:

image-20200824232924494
  • 用戶名和密碼:有寫服務(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 對于 GETHEAD 請求方法來說菩貌,當(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-SinceIf-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-TypeContent-Length
  • Multiple-resource bodies暑中,由多部分body組成壹瘟,每一部分包含不同的信息位。通常是和 HTML Forms 連系在一起鳄逾。

3.4.2稻轨、響應(yīng)消息體

并不是所有的響應(yīng)都有body,如 201204狀態(tài)碼的響應(yīng)一般不會(huì)有body雕凹。

響應(yīng)body可以分為三類:

  • Single-resource bodies殴俱,由已知長度的單個(gè)文件組成政冻。該類型 body 由兩個(gè) header 定義:Content-TypeContent-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ù)器支持且無法被處理闰围。只有GETHEAD是要求服務(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):

https://github.com/arthinking/java-tech-stack

java-tech-stack-info

關(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)系作者請加公眾號朋沮。


  1. Hypertext Transfer Protocol -- HTTP/1.1 2616. Retrieved from https://tools.ietf.org/html/rfc2616 ? ?

  2. HTTP. MDN web docs. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP ?

  3. CONNECT. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/CONNECT ?

  4. HTTP Headers. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers ?

  5. List of HTTP status codes. Retrieved from https://en.wikipedia.org/wiki/List_of_HTTP_status_codes ?

  6. https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status. Retrieved from https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status ?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛇券,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子樊拓,更是在濱河造成了極大的恐慌纠亚,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筋夏,死亡現(xiàn)場離奇詭異蒂胞,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)条篷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門骗随,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛤织,“玉大人,你說我怎么就攤上這事鸿染≈秆粒” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵涨椒,是天一觀的道長摊鸡。 經(jīng)常有香客問我,道長蚕冬,這世上最難降的妖魔是什么免猾? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮囤热,結(jié)果婚禮上猎提,老公的妹妹穿的比我還像新娘。我一直安慰自己赢乓,他們只是感情好忧侧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著牌芋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪松逊。 梳的紋絲不亂的頭發(fā)上躺屁,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機(jī)與錄音经宏,去河邊找鬼犀暑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛烁兰,可吹牛的內(nèi)容都是我干的耐亏。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼沪斟,長吁一口氣:“原來是場噩夢啊……” “哼广辰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起主之,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤择吊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后槽奕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體几睛,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年粤攒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了所森。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片囱持。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖焕济,靈堂內(nèi)的尸體忽然破棺而出洪唐,到底是詐尸還是另有隱情,我是刑警寧澤吼蚁,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布凭需,位于F島的核電站,受9級特大地震影響肝匆,放射性物質(zhì)發(fā)生泄漏粒蜈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一旗国、第九天 我趴在偏房一處隱蔽的房頂上張望枯怖。 院中可真熱鬧,春花似錦能曾、人聲如沸度硝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蕊程。三九已至,卻和暖如春驼唱,著一層夾襖步出監(jiān)牢的瞬間藻茂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工玫恳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辨赐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓京办,卻偏偏與公主長得像掀序,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子惭婿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

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

  • 理解 HTTP 協(xié)議對構(gòu)建網(wǎng)絡(luò)應(yīng)用是一個(gè)非巢还В基礎(chǔ)的要求,比如爬蟲類程序审孽,必須深入理解 Request 和 Reso...
    馬六甲的筆記閱讀 469評論 0 0
  • HTTP 報(bào)文是在 HTTP 應(yīng)用程序之間發(fā)送的數(shù)據(jù)塊县袱。這些數(shù)據(jù)塊以一些文本形式的元信息開頭,這些信息描述了報(bào)文的...
    妖艷貨閱讀 407評論 0 1
  • 狀態(tài)碼釋義使用100 Continue表示目前為止一切正常, 客戶端應(yīng)該繼續(xù)請求, 如果已完成請求則忽略佑力。一般用在...
    曹吉利閱讀 276評論 0 0
  • 超文本傳輸協(xié)議 超文本傳輸協(xié)議(英文:HyperText Transfer Protocol漓滔,縮寫:HTTP)是一...
    取個(gè)帥氣的名字真好閱讀 484評論 0 9
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友乖篷。感恩相遇响驴!感恩不離不棄。 中午開了第一次的黨會(huì)撕蔼,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,551評論 0 11