1 HTTP介紹
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。
它的發展是萬維網協會(World Wide Web Consortium)和Internet工作小組IETF(Internet Engineering Task Force)合作的結果。
它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先於圖形)等。
1.1 版本
最常用的是HTTP1.0/1.1
最新版本是HTTP2.0,與1.0/1.1相比,有了更高的性能、安全性和靈活性
以前的版本0.9等
2 HTTP協議
2.1 URL與資源
2.1.1 方案的世界
在TCP/IP模型中,所有的網絡連接都要使用方案,方案定義使用什么協議,比如http、ftp、telnet
一個標准的網絡請求包括:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
但在實際使用過程中,對於不同協議可以缺少某些信息,比如
ftp://192.168.169.121
http://www.baidu.com/index.html
對於http協議,主要的包括scheme(協議)、host(主機)和path(資源路徑)
2.1.2 URI、URL和URN
URI:統一資源標識符,包括URL和URN
URL:統一資源標識符,比如http://www.baidu.com/index.html就是一個URL
URN:統一資源名,它是無關物理位置的資源名定義,例子urn:ieft:rfc:2141
目前URN處於試驗階段,實際應用還很困難,在沒有特別說明時,一般我們說的URI就代表URL
2.1.3 媒體類型
在HTTP中,不管是word文件、js文件或者圖片都是資源,通可以通過URL進行請求,但每種不同的文件都要進行區分,以便服務端和客戶端進行正確處理,比如播放聲音、顯示文字。
因此,HTTP仔細地給每種要通過http請求響應傳輸的對象都打上名為MIME類型的數據格式標簽。
MIME: Multipurpose Internet Mail Extension 多用途因特網郵件擴展
最開始是為了解決電子郵件系統之間的問題,后來用於定義更多類型的多謀體內容。常見的MIME:
html:text/html
Ascii: text/plain
Json:text/json
Jpg:image/jpeg
Gif:image/gif
Ppt: application/vnd.ms-powerpoint
Quicktime:video/quicktime
2.2 協議介紹
2.2.1 協議棧
HTTP在TCP/IP協議棧中的位置
HTTP是基於TCP/IP的應用,因此HTTP無須關心網絡尋址、數據傳輸和拓撲結構
2.2.2 協議工作流程
在HTTP1.0/1.1中,HTTP采用請求響應模型來處理HTTP事務 HTTP事務有一條請求命令和一個響應結果組成,它們通過HTTP報文進行數據傳輸
注意:請求是從客戶端發往服務端,而響應是從服務端發回客戶端
HTTP的工作過程
- (1)客戶端連接到Web服務器
- (2)發送HTTP請求
- (3)服務器接受請求並返回HTTP響應
- (4)釋放連接TCP連接
- (5)客戶端瀏覽器解析HTML內容
3 HTTP報文
3.1 報文
HTTP1.0/1.1報文由三部分組成:起始行、首部以及可選、包含數據的主體
其中起始行和首部是由行分隔的ASCII文本
主體是一個可選的數據塊,主體中可以包含文本也可以包含二進制數據,也可以為空,與首部通過空一行進行區分
請求報文的格式:
<method> <request-url> <version>
<headers>
<entity-body>
響應報文的格式:
<version> <status> <reason-phrase>
<headers>
<entity-body>
具體例子:
3.1.1 起始行
所有的HTTP報文都以一個起始行做為開始
請求報文:<method> <request-url> <version> 說明要做什么
響應報文:<version> <status> <reason-phrase> 說明結果怎樣
- method,包括GET/POST/DELETE等等
- version,目前絕大多數都是1.0或者1.1
- status,表示做的結果
- reason-phrase,是對狀態結果的進一步補充說明
3.1.2 首部字段
HTTP首部字段向請求和響應報文中添加了一些附加信息,是一系列 key-value的列表,比如Content-Type:image/jpeg 表示類型是jpeg圖片
首部的分類包括
通用首部:在請求和響應中都出現的信息
請求首部:只在請求報文中出現的信息
響應首部:只在響應報文中出現的信息
實體首部:描述主題的長度、內容等的信息
擴展首部:在HTTP規范中沒有定義的其他信息
3.1.3 實體
HTTP實體是HTTP報文的負荷,是HTTP要傳輸的數據內容。
3.2 方法
HTTP基本的方法包括:GET/POST/HEAD/PUT/TRACE/OPTIONS,用來告訴服務端要做什么操作
3.2.1 GET
GET是最常用的方法,通常用於請求服務器發送某個資源
3.2.2 POST
POST是常用的方法之一,用於向服務端提交數據,有主體
3.2.3 HEAD
與GET類似,但在響應中只有首部,不返回具體數據,可以用來查看資源是否存在
3.2.4 PUT/TRACE/OPTIONS/DELETE
PUT:用於向服務端寫入文檔
TRACE:用於跟蹤某個請求
OPTIONS:用於查詢服務端支持的方法
DELETE:用於刪除服務端某個資源
3.2.5 其他擴展方法
HTTP在設計之初就被設計成可擴展的,這樣就可以適應新的特性。
擴展方法是在HTTP規范中沒有定義的方法,它們有特別的用處,但需要服務端進行實現:
LOCK:鎖定某個資源
COPY:拷貝某個資源
MOVE:移動某個資源
3.3 狀態碼
狀態碼是響應報文中對請求所做事情的處理結果,以方便客戶端處理響應數據
狀態碼分為五大類:
信息性狀態碼:100~199
成功狀態碼:200~299
重定向狀態碼:300~399
客戶端錯誤狀態碼:400~499
服務端錯誤狀態碼:500~599
3.3.1 信息性狀態碼
HTTP1.1引入的狀態碼,目前存在一些爭議
- 100-Continue:說明收到了請求的初始部分,請客戶端繼續
- 101-Switching Protocols:說明服務端正在根據客戶端的指定,將協議轉換成Update首部所列的協議
3.3.2 成功狀態碼
客戶端發起的請求大部分是成功,但成功也有不同的區別,所以用一組狀態來區分不同的信息
- 200-OK:沒有任何問題
- 201-Created:對於像PUT方法的響應,表示服務端創建了對象的請求
- 202-Accepted:請求已經被接受,但未執行任何動作,服務端不保證會完成這個請求
- 203-Non-Authoritative Information:實體首部包含的信息不是來自源端服務器,可能來自中間服務器,因此沒有進行驗證
- 204-No Content:沒有主體部分
- 205-Reset Content:告訴瀏覽器清除當前頁中的所有html元素
- 206-Partial Content:成功執行了部分請求
3.3.3 重定向狀態碼
重定向狀態碼告訴客戶端使用替代請求來訪問資源,或者返回一個請求以便客戶端使用這個請求訪問所需資源
主要的狀態碼:
- 302-Found:客戶端使用Location首部給出的URL來訪臨時訪問資源
- 304-Not Modified:標識請求的內容沒有改變,可以使用緩存數據
3.3.4 客戶端錯誤狀態碼
客戶端錯誤狀態碼標識客戶端發送了一些錯誤的信息給服務端
比如:
- 403-Forbidden:請求被服務端拒絕了,有可能是沒有權限訪問,也有可能是用戶名密碼錯誤
- 414-Request URI Too Long:請求的URL太長了
3.3.5 服務端錯誤狀態碼
標識服務端自身錯誤
比如:
- 503-Service Unavailable:服務端暫時無法提供服務,可能因為服務端啟動配置錯誤
- 505-HTTP Version Not Supported:服務端接收到了它無法支持的協議版本,不能處理
3.4 首部
首部和方法配合工作,共同決定了客戶端和服務端能做什么事情
主要包括:通用首部、請求首部、響應首部、實體首部
3.4.1 通用首部
通用首部是提供了報文的最基本信息,不論報文的類型,都為其提供一些有用信息
如上圖的Connection就是通用首部,在請求和響應報文中提供了連接的相關信息
- 通用性的首部還包括:Date、MIME-Version、Via、Update等等
- HTTP1.0引入了一個允許HTTP應用程序緩存對象副本的首部——Cache-Control,叫做通用緩存首部
3.4.2 請求首部
請求首部只在請求報文中出現,用於輔助說明誰在發送請求,請求來自何處等等
比如:
- Host:請求主機名和端口號
- User-Agent:告訴服務端發起請求的應用程序的名稱
3.4.3 響應首部
響應首部只在響應報文中出現,用於說明客戶端應該怎么去處理的一些額外信息
比如:
- Expires:該資源的過期時間
- Server:服務器應用程序軟件的名稱和版本
3.4.4 實體首部
實體首部用於標識實體的信息
比如:
- Content-Type:內容的類型
- Content-Length:內容的長度