《圖解 HTTP》讀書筆記
通信模型
HTTP 協(xié)議被用于客戶端和服務(wù)器之間的通信缤剧,請(qǐng)求訪問文本或者圖片等資源的一端稱為客戶端,而提供資源響應(yīng)的一端稱為服務(wù)器端。
在 HTTP 中規(guī)定,請(qǐng)求從客戶端發(fā)出,服務(wù)器收到請(qǐng)求并響應(yīng)后返回。HTTP 是一種無狀態(tài)(stateless)協(xié)議, HTTP 協(xié)議自身不對(duì)請(qǐng)求和響應(yīng)之間的通信狀態(tài)進(jìn)行保存传货,也就是說不對(duì)發(fā)送過的請(qǐng)求或者響應(yīng)做持久化處理。但是隨著技術(shù)發(fā)展宏娄,無狀態(tài)的 HTTP 協(xié)議很難滿足業(yè)務(wù)需要问裕,比如用戶登陸到一個(gè)網(wǎng)站之后,在這個(gè)網(wǎng)站的不同頁面跳轉(zhuǎn)的時(shí)候需要繼續(xù)保持用戶的登陸狀態(tài)孵坚。網(wǎng)站為了能夠掌握是哪個(gè)客戶端發(fā)出的請(qǐng)求粮宛,需要保存用戶的狀態(tài)。HTTP 為了實(shí)現(xiàn)保持狀態(tài)的功能卖宠,引入了我們熟知的 Cookie 技術(shù)來實(shí)現(xiàn)狀態(tài)管理巍杈。
HTTP 的 GET 方法
GET 方法用來請(qǐng)求訪問資源。如果請(qǐng)求的資源是文本扛伍,那么文本就保持原樣返回筷畦。如果請(qǐng)求的資源是 CGI 程序(Common Gateway Interface,通用網(wǎng)關(guān)接口),那么服務(wù)端返回經(jīng)過執(zhí)行后的輸出結(jié)果刺洒。
使用 GET 方法的請(qǐng)求鳖宾,請(qǐng)求 index.html 的頁面資源
使用 GET 方法的響應(yīng),返回 index.html 的頁面資源
HTTP 的 POST 方法
POST 方法通常用來提交數(shù)據(jù)給服務(wù)端逆航。雖然 GET 方法也可以用來提交數(shù)據(jù)鼎文,但一般并不使用 GET 方法。值得一提的是因俐,GET 方法的參數(shù)會(huì)以 QueryString 的形式跟在請(qǐng)求鏈接后面而 POST 方法不會(huì)拇惋,但是不管 HTTP 的 GET 方法還是 POST 方法都是不安全的周偎,請(qǐng)求數(shù)據(jù)都會(huì)被攔截。
HTTP 的報(bào)文結(jié)構(gòu)
HTTP 通行過程包括從客戶端發(fā)起請(qǐng)求和服務(wù)端響應(yīng)請(qǐng)求的過程蚤假。用于 HTTP 協(xié)議交互的信息稱為 HTTP 報(bào)文栏饮,客戶端的 HTTP 報(bào)文稱為請(qǐng)求報(bào)文,服務(wù)端的報(bào)文叫做響應(yīng)報(bào)文磷仰。HTTP 報(bào)文本身是由多行數(shù)據(jù)構(gòu)成的字符串文件。HTTP 報(bào)文大概可以分為 2 塊境蔼,一塊是報(bào)文首部灶平,一塊是報(bào)文主體,2 者之間使用空行來劃分箍土。通常情況下逢享,報(bào)文主體不一定存在。
請(qǐng)求報(bào)文和響應(yīng)報(bào)文的首部內(nèi)容由以下數(shù)據(jù)組成吴藻。
- 請(qǐng)求行瞒爬, 包括請(qǐng)求的方法,請(qǐng)求 URI 和 HTTP 版本
- 狀態(tài)行沟堡,表示響應(yīng)結(jié)果的狀態(tài)碼侧但,原因短語和 HTTP 版本
- 首部字段,表示請(qǐng)求和響應(yīng)的各種條件航罗,屬性的各類首部禀横。一般有 4 種首付,分別是通用首部粥血,請(qǐng)求首部柏锄,響應(yīng)首部和實(shí)體首部
- 其他
我們使用 GET 方法請(qǐng)求 http://hackr.jp/index.htm 鏈接,請(qǐng)求報(bào)文和響應(yīng)報(bào)文如
HTTP 提升傳輸效率
HTTP 在傳輸數(shù)據(jù)時(shí)既可以按照數(shù)據(jù)原貌直接傳輸复亏,也可以在傳輸過程中通過編碼來提升傳輸效率趾娃。為了讓 HTTP 報(bào)文的數(shù)據(jù)容量盡可能的小,HTTP 協(xié)議規(guī)定了一個(gè)內(nèi)容編碼的功能用于壓縮數(shù)據(jù)缔御。舉個(gè)例子抬闷,客戶端請(qǐng)求的內(nèi)容編碼說明了數(shù)據(jù)的編碼格式,HTTP協(xié)議按照編碼格式對(duì)數(shù)據(jù)內(nèi)容進(jìn)行編碼并傳輸刹淌,服務(wù)端接收數(shù)據(jù)后饶氏,HTTP 協(xié)議按照對(duì)應(yīng)的編碼格式對(duì)數(shù)據(jù)進(jìn)行解碼。常見的內(nèi)容編碼格式有 gzip,compress,deflate,identity有勾。
HTTP 分塊傳輸編碼
在 HTTP 通信過程中疹启,請(qǐng)求的編碼實(shí)體資源未全部完成傳輸之前,瀏覽器無法顯示資源蔼卡。所以設(shè)計(jì)人員設(shè)計(jì)了一個(gè)功能喊崖,叫做分塊傳輸編碼 (Chunked Transfer Coding)
分塊傳輸編碼會(huì)將實(shí)體主體分成多個(gè)部分挣磨。每一塊都會(huì)用十六進(jìn)制來標(biāo)記塊的大小,而實(shí)體主體的最后一塊會(huì)使用“ 0(CR+LF)”來標(biāo)記荤懂。使用分塊傳輸編碼的實(shí)體主體會(huì)由接收的客戶端來負(fù)責(zé)解碼茁裙,恢復(fù)到編碼前的實(shí)體主體。
HTTP 的 Multipart
HTTP 協(xié)議中規(guī)定节仿,發(fā)送的一份報(bào)文主體內(nèi)可以包含多種類型實(shí)體(Multipart)晤锥,比如文本,視頻廊宪,圖片矾瘾。通常在圖片或者文本文件上傳的時(shí)候會(huì)使用到這個(gè)功能。在 HTTP 報(bào)文中使用 Multipart 的時(shí)候需要在首部字段里面加上 Content-Type箭启,使用 boundary 來劃分不同的實(shí)體壕翩。在不同的實(shí)體的起始行前插入 “--” 標(biāo)記,而在 Multipart 的最后部分插入 “--” 標(biāo)記傅寡,如下圖所示的 --AaB03x放妈,--AaB03x--。
使用 Multipart/form-data 上傳表單
“Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x
Content-Disposition: form-data; name="field1"
Joe Blow
--AaB03x
Content-Disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
...(file1.txt的數(shù)據(jù))...
--AaB03x--”
使用 Multipart/byteranges 響應(yīng)荐操,狀態(tài)碼 206芜抒。該報(bào)文可以在需要響應(yīng)多個(gè)范圍的內(nèi)容時(shí)使用。在不同的實(shí)體的起始行前插入 “--” 標(biāo)記淀零,而在 Multipart 的最后部分插入 “--” 標(biāo)記挽绩,如下圖所示的 --THIS_STRING_SEPARATES,--THIS_STRING_SEPARATES--驾中。
“HTTP/1.1 206 Partial Content
Date: Fri, 13 Jul 2012 02:45:26 GMT
Last-Modified: Fri, 31 Aug 2007 02:02:20 GMT
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000
...(范圍指定的數(shù)據(jù))...
--THIS_STRING_SEPARATES
Content-Type: application/pdf”
“Content-Range: bytes 7000-7999/8000
...(范圍指定的數(shù)據(jù))...
--THIS_STRING_SEPARATES--”
HTTP 的 范圍請(qǐng)求 (Range Request)
HTTP 協(xié)議設(shè)計(jì)了這么一個(gè)功能唉堪,用戶下載大圖片過程中,若是遇到網(wǎng)絡(luò)中斷的情況肩民,在網(wǎng)絡(luò)恢復(fù)之后唠亚,可以從之前下載中斷處恢復(fù)。這種指定范圍發(fā)送的請(qǐng)求叫做范圍請(qǐng)求 (Range Request)持痰,通吃钏眩可以使用這個(gè)特性來做斷點(diǎn)下載功能。
對(duì)于一份 10 000 字節(jié)大小的資源工窍,可以使用 Range Request 只請(qǐng)求 5001 ~ 10 000 字節(jié)內(nèi)的資源割卖。
請(qǐng)求 5001 ~ 10 000 字節(jié),使用首部字段 Range 來指定資源的范圍
Range:bytes=5001-10000
從 5000 字節(jié)之后的全部范圍
Range:bytes=5001-
也可以指定多重范圍
Range:bytes=-3000,5000-7000
對(duì)于范圍請(qǐng)求 (Range Request)患雏,響應(yīng)會(huì)返回狀態(tài)碼 206 的響應(yīng)報(bào)文鹏溯,使用 Content-Range 來標(biāo)明響應(yīng)范圍。值的一提的是淹仑,若是服務(wù)端無法響應(yīng)范圍請(qǐng)求丙挽,那么服務(wù)端則會(huì)返回狀態(tài)碼 200 OK 和 完整的實(shí)體內(nèi)容肺孵。
對(duì)于多重范圍的范圍請(qǐng)求,響應(yīng)報(bào)文會(huì)在首部字段 Content-Type 標(biāo)明 multipart/byteranges 后返回響應(yīng)報(bào)文颜阐,如下所示平窘。
“HTTP/1.1 206 Partial Content
Date: Fri, 13 Jul 2012 02:45:26 GMT
Last-Modified: Fri, 31 Aug 2007 02:02:20 GMT
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000
...(范圍指定的數(shù)據(jù))...
--THIS_STRING_SEPARATES
Content-Type: application/pdf”
“Content-Range: bytes 7000-7999/8000
...(范圍指定的數(shù)據(jù))...
--THIS_STRING_SEPARATES--”
HTTP 狀態(tài)碼
HTTP 狀態(tài)碼的職責(zé)是當(dāng)客戶端向服務(wù)器發(fā)送請(qǐng)求是,描述返回的請(qǐng)求結(jié)果凳怨。利用狀態(tài)碼瑰艘,客戶端可以知道服務(wù)端是否正常處理了請(qǐng)求。
- 1XX猿棉,表示接收的請(qǐng)求正在處理
- 2XX磅叛,請(qǐng)求正常處理完畢
- 3XX,需要附加操作才能完成請(qǐng)求萨赁,也就是重定向
- 4XX,服務(wù)器無法處理請(qǐng)求兆龙,也就是客戶端錯(cuò)誤
- 5XX杖爽,服務(wù)器處理請(qǐng)求出錯(cuò),也就是服務(wù)器錯(cuò)誤
200 OK紫皇,表示客戶端發(fā)來的請(qǐng)求在服務(wù)端被正常處理了
204 No Content,表示客戶端發(fā)來的請(qǐng)求在服務(wù)端被成功處理慰安,但是響應(yīng)內(nèi)容中不返回實(shí)體的主體部分
206 Partial Content,表示客戶端發(fā)來的范圍請(qǐng)求被服務(wù)端處理了,響應(yīng)報(bào)文中包含由 Content-Range 指定范圍的實(shí)體內(nèi)容
301 Moved Permanently,表示客戶端請(qǐng)求的資源已經(jīng)被永久分配了新的
URI聪铺,以后使用資源的話要用新的 URI
302 Found,表示客戶端請(qǐng)求的資源已經(jīng)被分配了新的 URI,這次臨時(shí)使用這個(gè)新的 URI
303 See Other,表示客戶端請(qǐng)求對(duì)應(yīng)的資源存在著另一個(gè) URI化焕,應(yīng)使用 GET 方法定向獲取請(qǐng)求的資源
304 Not Modified,表示客戶端請(qǐng)求對(duì)應(yīng)的資源若是有發(fā)生變化,則響應(yīng)資源铃剔,若是沒有發(fā)生變化撒桨,響應(yīng)時(shí)不包含任何響應(yīng)的主體部分
400 Bad Request,表示客戶端的請(qǐng)求報(bào)文中存在語法錯(cuò)誤
401 Unauthorized,表示客戶端發(fā)送的請(qǐng)求需要有通過 HTTP 認(rèn)證的認(rèn)證信息
403 Forbidden,表示客戶端對(duì)資源的訪問請(qǐng)求被拒絕了,未獲得訪問授權(quán)可能是發(fā)生 403 的原因
404 Not Found,表示服務(wù)端上面無法找到請(qǐng)求的資源键兜,客戶端的 URI 錯(cuò)誤可能是發(fā)生 404 的原因
500 Internal Server Error,表示服務(wù)端在執(zhí)行請(qǐng)求的時(shí)候發(fā)生了錯(cuò)誤凤类。
503 Service Unavailable,表示服務(wù)器處于超負(fù)載或者停機(jī)維護(hù),現(xiàn)在無法處理請(qǐng)求普气。
HTTP 首部字段
HTTP 首部字段根據(jù)實(shí)際用途可以分為 4 個(gè)類型谜疤,這些首部字段只需了解常見的類型,其他類型遇到的時(shí)候可以自行搜索即可现诀。
- 通用首部字段夷磕,請(qǐng)求和響應(yīng)報(bào)文都會(huì)使用的首部
- 請(qǐng)求首部字段,從客戶端向服務(wù)器發(fā)送請(qǐng)求時(shí)使用的首部
- 響應(yīng)首部字段仔沿,從服務(wù)端向客戶端返回響應(yīng)報(bào)文時(shí)使用的首部
- 實(shí)體首部字段奋刽,針對(duì)請(qǐng)求和響應(yīng)報(bào)文的實(shí)體部分使用的首部
通用首部字段名 | 說明 |
---|---|
Cache-Control | 控制緩存的行為 |
Connection | 逐跳首部、連接的管理 |
Date | 創(chuàng)建報(bào)文的日期時(shí)間 |
Pragma | 報(bào)文指令 |
Trailer | 報(bào)文末端的首部一覽 |
Transfer-Encoding | 指定報(bào)文主體的傳輸編碼方式 |
Upgrade | 升級(jí)為其他協(xié)議 |
Via | 代理服務(wù)器的相關(guān)信息 |
Warning | 錯(cuò)誤通知 |
請(qǐng)求首部字段名 | 說明 |
---|---|
Accept | 用戶代理可處理的媒體類型 |
Accept-Charset | 優(yōu)先的字符集 |
Accept-Encoding | 優(yōu)先的內(nèi)容編碼 |
Accept-Language | 優(yōu)先的語言(自然語言) |
Authorization | Web認(rèn)證信息 |
Expect | 期待服務(wù)器的特定行為 |
From | 用戶的電子郵箱地址 |
Host | 請(qǐng)求資源所在服務(wù)器 |
If-Match | 比較實(shí)體標(biāo)記(ETag) |
If-Modified-Since | 比較資源的更新時(shí)間 |
If-None-Match | 比較實(shí)體標(biāo)記(與 If-Match 相反) |
If-Range | 資源未更新時(shí)發(fā)送實(shí)體 Byte 的范圍請(qǐng)求 |
If-Unmodified-Since | 比較資源的更新時(shí)間(與If-Modified-Since相反) |
Max-Forwards | 最大傳輸逐跳數(shù) |
Proxy-Authorization | 代理服務(wù)器要求客戶端的認(rèn)證信息 |
Range | 實(shí)體的字節(jié)范圍請(qǐng)求 |
Referer | 對(duì)請(qǐng)求中 URI 的原始獲取方 |
TE | 傳輸編碼的優(yōu)先級(jí) |
User-Agent | HTTP 客戶端程序的信息 |
響應(yīng)首部字段名 | 說明 |
---|---|
Accept-Ranges | 是否接受字節(jié)范圍請(qǐng)求 |
Age | 推算資源創(chuàng)建經(jīng)過時(shí)間 |
ETag | 資源的匹配信息 |
Location | 令客戶端重定向至指定URI |
Proxy-Authenticate | 代理服務(wù)器對(duì)客戶端的認(rèn)證信息 |
Retry-After | 對(duì)再次發(fā)起請(qǐng)求的時(shí)機(jī)要求 |
Server | HTTP服務(wù)器的安裝信息 |
Vary | 代理服務(wù)器緩存的管理信息 |
WWW-Authenticate | 服務(wù)器對(duì)客戶端的認(rèn)證信息 |
實(shí)體首部字段名 | 說明 |
---|---|
Allow | 資源可支持的HTTP方法 |
Content-Encoding | 實(shí)體主體適用的編碼方式 |
Content-Language | 實(shí)體主體的自然語言 |
Content-Length | 實(shí)體主體的大兴老唷(單位:字節(jié)) |
Content-Location | 替代對(duì)應(yīng)資源的URI |
Content-MD5 | 實(shí)體主體的報(bào)文摘要 |
Content-Range | 實(shí)體主體的位置范圍 |
Content-Type | 實(shí)體主體的媒體類型 |
Expires | 實(shí)體主體過期的日期時(shí)間 |
Last-Modified | 資源的最后修改日期時(shí)間 |