HTTP協(xié)議的核心部分:它傳輸?shù)膱笪膬?nèi)容
報文結(jié)構(gòu)
HTTP協(xié)議也是與TCP/UDP類似津函,同樣也需要在實際傳輸?shù)臄?shù)據(jù)前附加一些頭數(shù)據(jù),不過與TCP/UDP不同的是胧洒,它是一個“純文本”的協(xié)議雌澄,所以頭數(shù)據(jù)都是ASCII碼的文本脸哀,可以很容易地用肉眼閱讀嫁乘,不用借助程序解析也能夠看懂昆婿。
HTTP協(xié)議請求報文和響應(yīng)報文的結(jié)構(gòu)基本相同,由三大部分組成:
1.起始行(start line): 描述請求或響應(yīng)的基本信息;
2.頭部字段集合(header): 使用key-value形式更詳細地說明報文;
3.消息正文(entity): 實際傳輸?shù)臄?shù)據(jù)蜓斧,它不一定是純文本, 可以是圖片仓蛆、視頻等二進制數(shù)據(jù)
前兩部分起始行和頭部字段經(jīng)常又合稱為"請求頭"或"響應(yīng)頭", 消息正文又稱為"實體", 但與"header"對應(yīng),很多時候就直接稱為"body"
HTTP協(xié)議規(guī)定報文必須有header,但可以沒有body, 而且在header之后必須要有一個"空行", 也就是"CRLF", 十六進制的"0D0A"
請求行
請求報文的起始行也就是請求行, 簡要描述了客戶端想要如何操作服務(wù)器端的資源
請求行由三部分構(gòu)成:
1.請求方法: 是一個動詞挎春,如GET/POST, 表示對資源的操作
2.請求目標: 通常是一個URI, 標記了請求方法要操作的資源
3.版本號: 表示報文使用的HTTP協(xié)議版本
這三個部分通常使用空格(space)來分隔, 最后要用CRLF換行表示結(jié)束
狀態(tài)行
響應(yīng)報文里的起始行看疙,在這里不叫"響應(yīng)行", 而是叫"狀態(tài)行", 意思是服務(wù)器響應(yīng)的狀態(tài)
比起請求行來說, 狀態(tài)行要簡單一些豆拨,同樣也是由三部分構(gòu)成:
1.版本號: 表示報文使用的HTTP協(xié)議版本;
2.狀態(tài)碼: 一個三位數(shù), 用代碼的形式表示處理的結(jié)果,比如200是成功, 500是服務(wù)器錯誤
3.原因:作為數(shù)字狀態(tài)碼補充, 是更詳細的解釋文字能庆,幫助人解釋原因
頭部字段
請求行或狀態(tài)行再加上頭部字段集合就構(gòu)成了HTTP報文里完整的請求頭或響應(yīng)頭
請求頭和響應(yīng)頭的結(jié)構(gòu)是基本一樣的辽装,唯一的區(qū)別是起始行,所以我把請求頭和響應(yīng)頭的字段放在一起介紹
頭部字段里是key-value的形式相味,key和value之間用":"分隔, 最后用CRLF換行表示字段結(jié)束殉挽。比如在“Host: 127.0.0.1”這一行里key就是“Host”丰涉,value就是“127.0.0.1”。
HTTP頭字段非常靈活斯碌,不僅可以使用標準里的Host一死、Connection等已有頭,也可以任意添加自定義頭傻唾,這就給HTTP協(xié)議帶來了無限的擴展可能投慈。
使用頭字段需要注意以下幾點:
1.字段名不區(qū)分大小寫,例如"Host"也可以寫成"host", 但首字母大寫的可讀性更好
2.字段名里不允許出現(xiàn)空格冠骄,可以使用連字符“
-”伪煤,但不能使用下劃線“_”。例如凛辣,“test-name”是合法的字段名抱既,而“test name”“test_name”是不正確的字段名;
3.字段名后面必須緊接著":", 不能有空格, 而":"后的字段值前可以有多個空格
4.字段的順序是沒有意義的扁誓,可以任意排列不影響語義
5.字段原則上不能重復(fù)防泵,除非這個字段本身的語義允許, 例如Set-Cookie
常用頭字段
HTTP協(xié)議規(guī)定了非常多的頭部字段, 基本上可以分為以下四類:
1.通用字段:在請求頭和響應(yīng)頭里都可以出現(xiàn);
2.請求字段:僅能出現(xiàn)在請求頭里蝗敢,進一步說明請求信息或者額外的附加條件捷泞;
3.響應(yīng)字段:僅能出現(xiàn)在響應(yīng)頭里,補充說明響應(yīng)報文的信息寿谴;
- 實體字段:它實際上屬于通用字段锁右,但專門描述body的額外信息