HTTP 報(bào)文是在 HTTP 應(yīng)用程序之間發(fā)送的數(shù)據(jù)塊。這些數(shù)據(jù)塊以一些文本形式的元信息開(kāi)頭,這些信息描述了報(bào)文的內(nèi)容及含義。
報(bào)文流
報(bào)文在客戶端、服務(wù)器和代理之間的流動(dòng)稱為報(bào)文流。 HTTP 使用術(shù)語(yǔ)流入和流出來(lái)描述事務(wù)處理的方向。報(bào)文像水一樣都是從上游流向下游,不會(huì)從下游流向上游。假定客戶端和服務(wù)器之間有兩個(gè)代理服務(wù)器,客戶端發(fā)送一個(gè)請(qǐng)求,服務(wù)器進(jìn)行響應(yīng),期間報(bào)文流向?yàn)椋嚎蛻舳?-> 代理1 ->代理2 -> 服務(wù)器 -> 代理2 -> 代理1 -> 客戶端。

報(bào)文的組成部分
每條報(bào)文都包含一條來(lái)自客戶端的請(qǐng)求,或者來(lái)自服務(wù)器的響應(yīng)。它們由三部分組成:對(duì)報(bào)文進(jìn)行描述的起始行,包含屬性的首部塊,以及可選的、包含數(shù)據(jù)的主體部分。
起始行和首部是由行分隔的 ASCII 文本,每行的行終止符都由一個(gè)回車(chē)符和一個(gè)換行符組成,可書(shū)寫(xiě)成 CRLF。主體可以包含文本數(shù)據(jù)或二進(jìn)制數(shù)據(jù),也可以為空。
延伸:Unix 系統(tǒng)里,每行結(jié)尾只有“<換行>”,即“\n”;Windows系統(tǒng)里面,每行結(jié)尾是“ <回車(chē)><換 行>”,即“\r\n”;Mac系統(tǒng)里,每行結(jié)尾是“<回車(chē)>”。一個(gè)直接后果是,Unix/Mac系統(tǒng)下的文件在Windows里打 開(kāi)的話,所有文字會(huì)變成一行;而Windows里的文件在Unix/Mac下打開(kāi)的話,在每行的結(jié)尾可能會(huì)多出一個(gè)^M符號(hào)。
所有的 HTTP 報(bào)文都可以分為兩類(lèi):請(qǐng)求報(bào)文和響應(yīng)報(bào)文,兩者的基本報(bào)文結(jié)構(gòu)相同,具體內(nèi)容有些許差別。

請(qǐng)求報(bào)文的格式如下:
<method> <request-URL> <version> // 起始行
<headers> // 首部
<entity-body> // 主體
響應(yīng)報(bào)文格式如下,
<version> <status> <reason-phrase> // 起始行
<headers> // 首部
<entity-body> // 主體
下面對(duì)報(bào)文格式中的每一項(xiàng)進(jìn)行概述性解釋?zhuān)?/p>
方法(method)
請(qǐng)求的起始行以方法作為開(kāi)始,用來(lái)告訴服務(wù)器要做什么。比如 GET /test/index.text HTTP/1.1 , 方法是 GET,請(qǐng)求從服務(wù)器拿到 /test/idnex.text 文件內(nèi)容。常用的 HTTP 方法有,
| HTTP 方法 | 描述 | 是否包含請(qǐng)求主體 |
|---|---|---|
| GET | 安全方法,服務(wù)器向客戶端發(fā)送命名資源 | 否 |
| PUT | 將來(lái)自客戶端的數(shù)據(jù)存儲(chǔ)到一個(gè)命名的服務(wù)器資源中去 | 是 |
| POST | 將客戶端數(shù)據(jù)發(fā)送到一個(gè)服務(wù)器網(wǎng)關(guān)應(yīng)用程序 | 是 |
| DELETE | 從服務(wù)器刪除命名資源,客戶端無(wú)法保證刪除請(qǐng)求一定被執(zhí)行,因?yàn)?HTTP 規(guī)范允許服務(wù)器在不通知客戶端的情況下撤銷(xiāo)請(qǐng)求 | 否 |
| HEAD | 安全方法,僅發(fā)送命名資源響應(yīng)中的 HTTP 首部 ,用于在不獲取實(shí)際資源的情況下對(duì)資源首部進(jìn)行檢查,判斷某個(gè)對(duì)象是否存在,測(cè)試資源是否被修改 | 否 |
| TRACE | 對(duì)可能經(jīng)過(guò)的代理服務(wù)器傳送到服務(wù)器上去的報(bào)文進(jìn)行追蹤,用于查看原報(bào)文是否被更改過(guò),或進(jìn)行了何種更改 | 否 |
| OPTIONS | 決定可以在服務(wù)器上執(zhí)行哪些方法 | 否 |
以上方法并不是所有瀏覽器都支持,也不是所有服務(wù)器都支持。安全方法指不會(huì)在服務(wù)器上執(zhí)行任何內(nèi)容變更并產(chǎn)生任何結(jié)果的方法。
雖然方法有這么多,但目前瀏覽器上的請(qǐng)求幾乎被 GET 和 POST 包攬,這是為什么呢?下面有個(gè)非官方的網(wǎng)友回答,覺(jué)得解釋得通不錯(cuò),于是摘錄,
按照定義,假設(shè)有資源組A,內(nèi)部包含該1、2、3這些資源,則
獲取資源A1:Get Url A1
新增資源A4:Post Url A + RAWDATA 4
修改資源A4:Put Url A + RAWDATA 4
刪除資源A2:Delete Url A2
然而實(shí)際上多數(shù)人都這么做
獲取資源A1:Get Url A1
新增資源A4:Post Url A + RAWDATA 4
修改資源A4:Post Url A4 + RAWDATA 4
刪除資源A2:Get Url delete A1
即使是新浪的微博都 POST Url+access_token + RAWDATA empty 的方式使用。更多的人都在用 Get + delete 參數(shù)的方式來(lái)實(shí)現(xiàn),不知道他們的理由是不知道、不理解、還是不愿意。
再者,網(wǎng)絡(luò)環(huán)境惡劣,其實(shí)很多情況下我們網(wǎng)絡(luò)的80端口是被劫持的么,而二級(jí)運(yùn)營(yíng)商則幾乎100%都是被劫持的。某些設(shè)備劫持之后會(huì)代理你進(jìn)行http訪問(wèn),而這些設(shè)備是不認(rèn)識(shí)其他請(qǐng)求方式的。代理不認(rèn)識(shí),就無(wú)法進(jìn)行正常的識(shí)別和轉(zhuǎn)發(fā),這就導(dǎo)致其它協(xié)議無(wú)法正常使用。
某些二級(jí)運(yùn)營(yíng)商的劫持設(shè)備,Get、Post、Connection,如果遇到其他請(qǐng)求方式,就會(huì)返回你403錯(cuò)誤或者500或者502。像現(xiàn)在有大量的跨域請(qǐng)求需要Option,遇到這種網(wǎng)絡(luò)就完全報(bào)廢了。本身這里就很不正常了,然而它返回的狀態(tài)碼也是錯(cuò)的,錯(cuò)誤的請(qǐng)求方式,一般都是400、405等,但指責(zé)一個(gè)本身就不正常的設(shè)備有小毛病,是沒(méi)有意義的。
(以上回答摘自:https://segmentfault.com/q/1010000007736404)
版本(version)
報(bào)文所使用的 HTTP 版本格式為 HTTP/<major>.<minor>,其中主要版本號(hào)(majoi) 和 次要版本號(hào)(minor)都是整數(shù)。版本號(hào)的說(shuō)明是指應(yīng)用程序支持的最高 HTTP 版本,而非明確的某一版本。與 HTTP 1.1 的應(yīng)用程序進(jìn)行通信的 HTTP 1.2 應(yīng)用程序應(yīng)該知道它不能支持任何 HTTP 1.2 的新特性,最多只能支持到 HTTP 1.1 的特性。
狀態(tài)碼(status)和原因短語(yǔ)(reason-phrase)
狀態(tài)碼和原因短語(yǔ)是服務(wù)器用來(lái)告訴客戶端發(fā)生了什么的描述。原因短語(yǔ) 是 狀態(tài)碼 的可讀版本,對(duì)人類(lèi)閱讀解釋狀態(tài)碼有重要意義。比如:服務(wù)器返回狀態(tài)碼 304 Not Modified ,其中原因短語(yǔ) Not Modified 就是對(duì) 狀態(tài)碼 304 的解釋?zhuān)勺x性和可記憶性更強(qiáng)。
狀態(tài)碼位于響應(yīng)報(bào)文的起始行中,通過(guò)三個(gè)數(shù)字代碼對(duì)不同狀態(tài)碼進(jìn)行分類(lèi),如下表,
| 整體范圍 | 分類(lèi) |
|---|---|
| 100 ~ 199 | 信息提示, 如:101 Switching Protocols,說(shuō)明服務(wù)器正在根據(jù)客戶端的指定,將協(xié)議切換成 Update 首部所列的協(xié)議 |
| 200 ~ 299 | 成功,如: 200 OK,請(qǐng)求沒(méi)問(wèn)題,實(shí)體的主體部分包含了所請(qǐng)求的資源 |
| 300 ~ 399 | 重定向,如 301 Moved Permanently,請(qǐng)求的 URL 資源已被永久移除,響應(yīng)頭 location 首部應(yīng)該包含資源現(xiàn)在的 URL;304 Not Modified,資源未更改,無(wú)需從服務(wù)器下載資源 |
| 400 ~ 499 | 客戶端錯(cuò)誤,如 404 Not Found,服務(wù)器無(wú)法找到所請(qǐng)求的 URL |
| 500 ~ 599 | 服務(wù)器錯(cuò)誤, 如 504 Gateway Timeout,響應(yīng)來(lái)自網(wǎng)關(guān)或代理,在等待另一服務(wù)器時(shí)對(duì)請(qǐng)求進(jìn)行響應(yīng)超時(shí)了 |
緩存
200 ok / 200 from cache/ 200 from disk cache/ 304 not modified
首部(Headers)
通用首部
有些首部提供了與報(bào)文相關(guān)的最基本的信息,被稱為通用首部。這些首部既可以用于請(qǐng)求報(bào)文,也可以用于響應(yīng)報(bào)文。
| 首部 | 描述 |
|---|---|
| Connection | 允許客戶端和服務(wù)器指定與請(qǐng)求/響應(yīng)連接有關(guān)的數(shù)據(jù)。如, HTTP 1.0 需要保持客戶端與服務(wù)器之間的連接,就要設(shè)置 Connection: keep-alive |
| Date | 提供日期和時(shí)間標(biāo)志,說(shuō)明報(bào)文是什么時(shí)間創(chuàng)建的 |
| Trailer | 如果報(bào)文采用了分塊傳輸代碼方式,就可以用這個(gè)首部列出位于報(bào)文拖鞋部分的首部集合 |
| Transfer-Encoding | 告知接收端為了保證報(bào)文的可靠傳輸,對(duì)報(bào)文采用什么編碼方式 |
| Via | 顯示了報(bào)文經(jīng)過(guò)的中間節(jié)點(diǎn) |
| Cache-control | 用于隨報(bào)文傳送緩存指示,瀏覽器請(qǐng)求返回 304 狀態(tài)碼便和 Cache-control 息息相關(guān) |
請(qǐng)求首部
請(qǐng)求首部是只在請(qǐng)求報(bào)文中有意義的首部。用于說(shuō)明是誰(shuí)或說(shuō)明在發(fā)送請(qǐng)求、請(qǐng)求來(lái)自何處,或者客戶端的喜好及能力。
| 首部 | 描述 |
|---|---|
| User-agent | 將發(fā)起請(qǐng)求的應(yīng)用程序名稱告知服務(wù)器,如: iMac 上使用 Chrome 發(fā)送請(qǐng)求, User-agent 可能就是 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
|
| Accept | 告訴服務(wù)器能夠發(fā)送那些媒體類(lèi)型 |
| Accept-Encoding | 告訴服務(wù)器能夠發(fā)送哪些編碼方式 |
| Accept-Language | 告訴服務(wù)器能夠發(fā)送哪些自然語(yǔ)言 |
| Cookie | 客戶端向服務(wù)器發(fā)送一個(gè)令牌。用戶登錄的實(shí)現(xiàn)基本上需要用到 Cookie ,設(shè)置好之后,由瀏覽器在每個(gè)請(qǐng)求后自動(dòng)發(fā)送 |
| Proxy-Connection | 與 Connection 首部相同,但這個(gè)首部用在同啞代理(無(wú)法識(shí)別 connection: keep-alive 的代理)中使用 |
請(qǐng)求首部字段 Referer
一般Referer主要用于統(tǒng)計(jì),像百度統(tǒng)計(jì)可以通過(guò) Referer 統(tǒng)計(jì)訪問(wèn)流量的來(lái)源和搜索的關(guān)鍵詞。Referer 是由瀏覽器自動(dòng)加上的,刷新頁(yè)面也不會(huì)消失,但某些情況不會(huì)發(fā)送 Referer 頭部,如下:
● 直接輸入網(wǎng)址或通過(guò)瀏覽器書(shū)簽訪問(wèn)
● 來(lái)源頁(yè)面采用的協(xié)議為表示本地文件的 "file" 或者 "data" URI
● 當(dāng)前請(qǐng)求頁(yè)面采用的是非安全協(xié)議,而來(lái)源頁(yè)面采用的是安全協(xié)議 HTTPS(摘自 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer, 對(duì)此持有懷疑態(tài)度,驗(yàn)證未通過(guò),驗(yàn)證結(jié)果詳情參見(jiàn)下文)
通過(guò) Google 搜索 “風(fēng)鈴” ,然后訪問(wèn) zhan.qq.com ,可以看到請(qǐng)求頭中包含 referer 頭部,顯示 https://www.google.com.hk/(風(fēng)鈴的域名是 zhan.qq.com), 如下圖,

直接在瀏覽器中輸入網(wǎng)址: zhan.qq.com 可以看到,請(qǐng)求頭中并沒(méi)有出現(xiàn) referer 頭部,如下圖,

通過(guò) file 協(xié)議地址跳轉(zhuǎn)至目標(biāo)網(wǎng)站 zhan.qq.com ,可以看到,請(qǐng)求頭中依舊沒(méi)有出現(xiàn) referer 頭部,如下圖,


Google 安全協(xié)議 HTTPS 跳轉(zhuǎn)至 智慧校園 非安全協(xié)議 HTTP 依舊有 referer 出現(xiàn) ,與 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer 中描述的 “當(dāng)前請(qǐng)求頁(yè)面采用的是非安全協(xié)議,而來(lái)源頁(yè)面采用的是安全協(xié)議 HTTPS ” 該情況不會(huì)產(chǎn)生 referer不一致,

響應(yīng)首部
響應(yīng)報(bào)文有自己的首部集,首部集為客戶端提供一些額外的信息,比如 誰(shuí)在發(fā)送響應(yīng)、響應(yīng)者的功能,甚至與響應(yīng)相關(guān)的一些特殊指令。
| 首部 | 描述 |
|---|---|
| Age | 從最初創(chuàng)建開(kāi)始響應(yīng)持續(xù)時(shí)間 |
| Server | 服務(wù)器應(yīng)用程序軟件的名稱和版本 |
| Warning | 比原因短語(yǔ)更詳細(xì)一些的警告報(bào)文 |
| Proxy-Authenticate | 來(lái)自代理的對(duì)客戶端的質(zhì)詢列表,指定了獲取 proxy server(代理服務(wù)器)上的資源訪問(wèn)權(quán)限而采用的身份驗(yàn)證方式 |
| www-Authenticate | 來(lái)自服務(wù)器的對(duì)客戶端的質(zhì)詢列表,使用這些驗(yàn)證方式去獲取對(duì)資源的連接 |
實(shí)體的主體部分
實(shí)體首部提供了有關(guān)實(shí)體機(jī)器內(nèi)容的大量信息,從有關(guān)對(duì)象類(lèi)型的信息,到能夠?qū)Y源使用的各種有效的請(qǐng)求方法。
| 首部 | 描述 |
|---|---|
| Allow | 列出了可以對(duì)此實(shí)體執(zhí)行的請(qǐng)求方法 |
| Location | 告知客戶端實(shí)體實(shí)際上位于何處,用于將接受端定位到資源的位置上去 |
| Content-Length | 主體的長(zhǎng)度或尺寸 |
| Content-MD5 | 主體的 MD5 校驗(yàn)和 |
| Content-type | 主體對(duì)象類(lèi)型 |
| ETag | 某個(gè)特定資源的版本標(biāo)識(shí)符, 服務(wù)器返回 304 狀態(tài)碼與其息息相關(guān) |
| Expires | 實(shí)體不再有效,要從原始的源端再次獲取此實(shí)體的日期和時(shí)間 |
| Last-Modified | 這個(gè)實(shí)體最后一次被修改的日期和時(shí)間 |
Cache-Control與Expires的作用一致,Last-Modified與ETag的作用也相近。Cache-Control 與 ETag 出現(xiàn)于較新的 HTTP/1.1 版本,優(yōu)先級(jí)高于 Expires 和 Lat-Modified 。一般情況使用兩對(duì)中的一對(duì)即可。Cache-Control 和 ETag 決定了 服務(wù)器是否返回 304 狀態(tài)碼, 詳情請(qǐng)參考 http://mp.weixin.qq.com/s/k-ZtFUG674V0WAdQs3li8Q
如果想知道 請(qǐng)求結(jié)果 200 from cache, 304 的區(qū)別,具體可以參看: http://mp.weixin.qq.com/s/O6Ko7Sl3zsyzqGz9K_ORRw, 而兩者最大的區(qū)別是 200 from cache 不會(huì)向服務(wù)器發(fā)送請(qǐng)求,而 304 會(huì)向服務(wù)器發(fā)送請(qǐng)求,只是不會(huì)下載資源文件。
下圖是京東(www.jd.com)首頁(yè)請(qǐng)求部分截圖,出現(xiàn)了 200 from disk cache 和 200 from memory cache , 兩者由之前的 from cache 演變而來(lái),如果想知道二者的區(qū)別,請(qǐng)參看 https://www.quora.com/What-is-the-difference-between-memory-cache-and-disk-cache-in-Chrome, 大意是 內(nèi)存 比 硬盤(pán)讀取速度快很多,但內(nèi)存會(huì)隨著進(jìn)程的關(guān)閉(瀏覽器的關(guān)閉)而清除,但硬盤(pán)上的則不會(huì),所以瀏覽器會(huì)根據(jù)實(shí)際情況選擇兩種緩存方式,先從內(nèi)存中讀取資源,沒(méi)有,再?gòu)挠脖P(pán)讀取,再?zèng)]有,發(fā)送請(qǐng)求,此時(shí)服務(wù)器可能返回 304,也可能返回 200 OK,不會(huì)返回 200 from disk cache 或 200 from memory cache。

【參考內(nèi)容】
1.《HTTP 權(quán)威指南》David Gourley 等編. 陳涓 趙振平譯. 人民郵電出版社
只有足夠努力,才能看起來(lái)好不費(fèi)力?!?妖艷貨