[toc]
# HTTP 消息結(jié)構(gòu)
* 基于
HTTP是基于客戶端/服務(wù)端(C/S)的架構(gòu)模型,通過一個(gè)可靠的鏈接來交換信息,是一個(gè)無狀態(tài)的請(qǐng)求/響應(yīng)協(xié)議。
* HTTP"客戶端" 請(qǐng)求者
一個(gè)HTTP"客戶端"是一個(gè)應(yīng)用程序(Web瀏覽器或其他任何客戶端),通過連接到服務(wù)器達(dá)到向服務(wù)器發(fā)送一個(gè)或多個(gè)HTTP的請(qǐng)求的目的。
* HTTP"服務(wù)器" 反饋者
一個(gè)HTTP"服務(wù)器"同樣也是一個(gè)應(yīng)用程序(通常是一個(gè)Web服務(wù),如Apache Web服務(wù)器或IIS服務(wù)器等),通過接收客戶端的請(qǐng)求并向客戶端發(fā)送HTTP響應(yīng)數(shù)據(jù)。
* URL作用
HTTP使用統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifiers, URI)來傳輸數(shù)據(jù)和建立連接。
一旦建立連接后,數(shù)據(jù)消息就通過類似Internet郵件所使用的格式[RFC5322]和多用途Internet郵件擴(kuò)展(MIME)[RFC2045]來傳送。
* HTTP協(xié)議的報(bào)文格式
客戶端發(fā)送的HTTP報(bào)文,我們稱為請(qǐng)求鏈;中介服務(wù)器或Web服務(wù)器發(fā)送的HTTP報(bào)文,稱為響應(yīng)鏈。兩種報(bào)文都遵循以下格式:
* 一般開始行,即請(qǐng)求報(bào)文的請(qǐng)求行和應(yīng)答報(bào)文的狀態(tài)行;
* 總頭;
* 報(bào)文頭;
* 一個(gè)空行;
* 報(bào)文體
* 示例結(jié)構(gòu)
![](/upload/attach/202011/202011241524_MEHQV3A3XTKV5F4.png)
## 客戶端請(qǐng)求消息
客戶端發(fā)送一個(gè)HTTP請(qǐng)求到服務(wù)器的請(qǐng)求消息包括以下格式:請(qǐng)求行(request line)、請(qǐng)求頭部俗稱報(bào)頭(header)、空行和請(qǐng)求數(shù)據(jù)四個(gè)部分組成,如下圖所示:
![](/upload/attach/202011/202011241533_RSZBK6EAZWX6U7P.png)
* 請(qǐng)求行:
```
POST /orgid/idtoken/conditional HTTP/1.1
[請(qǐng)求方法] [url] [版本] (空格其分割區(qū)分作用)
```
* 報(bào)頭
```
Host :請(qǐng)求的資源在哪個(gè)主機(jī)的端口上
Connection:該請(qǐng)求支持長(zhǎng)連接(heep_alive)
Content-Length:正文內(nèi)容長(zhǎng)度
Content-Type:數(shù)據(jù)類型
User-Agent:聲明用戶的操作系統(tǒng)和瀏覽器版本信息
Accent:發(fā)起了請(qǐng)求
Referer:當(dāng)前頁(yè)面是從哪個(gè)頁(yè)面跳轉(zhuǎn)過來的
Accept-Encoding:接受的編碼
Accept-Language:接受的語言類型
Cookie:用于在客戶端存儲(chǔ)少量信息,通常用于實(shí)現(xiàn)會(huì)話(session)功能
```
* 空行
它的作用是通過一個(gè)空行,告訴服務(wù)器請(qǐng)求頭部到此為止。
* 請(qǐng)求數(shù)據(jù)
注意:若方法字段是GET,則此項(xiàng)為空,沒有數(shù)據(jù)
若方法字段是POST,則通常來說此處放置的就是要提交的數(shù)據(jù)
舉例:比如要使用POST方法提交一個(gè)表單,其中有user字段中數(shù)據(jù)為“admin”, password字段為123456,那么這里的請(qǐng)求數(shù)據(jù)就是 user=admin&password=123456,使用&來連接各個(gè)字段。
## 服務(wù)器響應(yīng)消息
HTTP響應(yīng)也由四個(gè)部分組成,分別是:響應(yīng)行、響應(yīng)報(bào)頭、空行和響應(yīng)正文。
* 響應(yīng)行
響應(yīng)行一般由協(xié)議版本、狀態(tài)碼及其描述組成 比如 HTTP/1.1 200 OK
其中協(xié)議版本HTTP/1.1或者HTTP/1.0,200就是它的狀態(tài)碼,OK則為它的描述。
* 響應(yīng)頭
響應(yīng)頭用于描述服務(wù)器的基本信息,以及數(shù)據(jù)的描述,服務(wù)器通過這些數(shù)據(jù)的描述信息,可以通知客戶端如何處理等一會(huì)兒它回送的數(shù)據(jù)。
**常見的響應(yīng)頭字段含義:**
```
Allow:服務(wù)器支持哪些請(qǐng)求方法(如GET、POST等)。
```
```
Content-Encoding:文檔的編碼(Encode)方法。只有在解碼之后才可以得到Content-Type頭指定的內(nèi)容類型。
```
```
Content-Length:表示內(nèi)容長(zhǎng)度。只有當(dāng)瀏覽器使用持久HTTP連接時(shí)才需要這個(gè)數(shù)據(jù)。
```
```
Content- Type:表示后面的文檔屬于什么MIME類型。
```
```
Date:當(dāng)前的GMT時(shí)間,例如,Date:Mon,31Dec200104:25:57GMT。
```
```
Expires:告訴瀏覽器把回送的資源緩存多長(zhǎng)時(shí)間,-1或0則是不緩存。
```
```
Last-Modified:文檔的最后改動(dòng)時(shí)間??蛻艨梢酝ㄟ^If-Modified-Since請(qǐng)求頭提供一個(gè)日期,該請(qǐng)求將被視為一個(gè)條件GET,只有改動(dòng)時(shí)間遲于指定時(shí)間的文檔才會(huì)返回,否則返回一個(gè)304(Not Modified)狀態(tài)。Last-Modified也可用setDateHeader方法來設(shè)置。
```
```
Location:這個(gè)頭配合302狀態(tài)碼使用,用于重定向接收者到一個(gè)新URI地址。表示客戶應(yīng)當(dāng)?shù)侥睦锶ヌ崛∥臋n。
```
```
Refresh:告訴瀏覽器隔多久刷新一次,以秒計(jì)。
```
```
Server:服務(wù)器通過這個(gè)頭告訴瀏覽器服務(wù)器的類型。Server響應(yīng)頭包含處理請(qǐng)求的原始服務(wù)器的軟件信息。此域能包含多個(gè)產(chǎn)品標(biāo)識(shí)和注釋,產(chǎn)品標(biāo)識(shí)一般按照重要性排序。Servlet一般不設(shè)置這個(gè)值,而是由Web服務(wù)器自己設(shè)置。
```
```
Set-Cookie:設(shè)置和頁(yè)面關(guān)聯(lián)的Cookie。
```
```
Transfer-Encoding:告訴瀏覽器數(shù)據(jù)的傳送格式。
```
```
WWW-Authenticate:客戶應(yīng)該在Authorization頭中提供什么類型的授權(quán)信息?在包含401(Unauthorized)狀態(tài)行的應(yīng)答中這個(gè)頭是必需的。
```
```
setContentType:設(shè)置Content-Type頭。大多數(shù)Servlet都要用到這個(gè)方法。
```
```
setContentLength:設(shè)置Content-Length頭。對(duì)于支持持久HTTP連接的瀏覽器來說,這個(gè)函數(shù)是很有用的。
```
```
addCookie:設(shè)置一個(gè)Cookie(Servlet API中沒有setCookie方法,因?yàn)閼?yīng)答往往包含多個(gè)Set-Cookie頭)。
```
```
插入代碼
```
* 空行
它的作用是通過一個(gè)空行,告訴響應(yīng)端響應(yīng)頭部到此為止。
* 響應(yīng)體
響應(yīng)體就是響應(yīng)的消息體,如果是純數(shù)據(jù)就是返回純數(shù)據(jù),如果請(qǐng)求的是HTML頁(yè)面,那么返回的就是HTML代碼,如果是JS就是JS代碼,如此之類。
# 參考資料
* 《HTTP請(qǐng)求/響應(yīng)報(bào)文結(jié)構(gòu)》
* 《HTTP教程》