HTTP請求報文格式就如下圖所示:
1. 請求報文
一個HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求數據4個部分組成。
大致結構是這樣的:
<request-line> //請求行
<headers> //首部行
<blank line> //空行
<request-body> //請求體
一個簡單的例子:
POST /user HTTP/1.1 //請求行
Host: www.user.com
Content-Type: application/x-www-form-urlencoded
Connection: Keep-Alive
User-agent: Mozilla/5.0. //以上是首部行
(此處必須有一空行) //空行分割header和請求內容
name=world 請求體
1.1 請求行
請求行由三部分組成:請求方法,請求URL(不包括域名),HTTP協議版本
請求方法比較多:GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT
最常用的是GET和POST。
1.1.1 請求方法
1) GET
傳遞參數長度受限制,因為傳遞的參數是直接表示在地址欄中,而特定瀏覽器和服務器對url的長度是有限制的。
因此,GET不適合用來傳遞私密數據,也不適合拿來傳遞大量數據。
一般的HTTP請求大多都是GET。
2)POST
POST把傳遞的數據封裝在HTTP請求數據中,以名稱/值的形式出現,可以傳輸大量數據,對數據量沒有限制,也不會顯示在URL中。
表單的提交用的是POST。
3)HEAD
HEAD跟GET相似,不過服務端接收到HEAD請求時只返回響應頭,不發送響應內容。所以,如果只需要查看某個頁面的狀態時,用HEAD更高效,因為省去了傳輸頁面內容的時間。
4)DELETE
刪除某一個資源。
5)OPTIONS
用於獲取當前URL所支持的方法。若請求成功,會在HTTP頭中包含一個名為“Allow”的頭,值是所支持的方法,如“GET, POST”。
6)PUT
把一個資源存放在指定的位置上。
本質上來講, PUT和POST極為相似,都是向服務器發送數據,但它們之間有一個重要區別,PUT通常指定了資源的存放位置,而POST則沒有,POST的數據存放位置由服務器自己決定。
關於POST和PUT的區別以及請求方法的冪等性,請參考文章:http的7種請求方法和冪等性
7)TRACE
回顯服務器收到的請求,主要用於測試或診斷。
8)CONNECT
CONNECT方法是HTTP/1.1協議預留的,能夠將連接改為管道方式的代理服務器。通常用於SSL加密服務器的鏈接與非加密的HTTP代理服務器的通信。
1.1.2 HTTP協議版本
1)HTTP/1.0
HTTP/1.0支持:GET、POST、HEAD三種HTTP請求方法。
2)HTTP/1.1
HTTP/1.1是當前正在使用的版本。該版本默認采用持久連接,並能很好地配合代理服務器工作。還支持以管道方式同時發送多個請求,以便降低線路負載,提高傳輸速度。
HTTP/1.1新增了:OPTIONS、PUT、DELETE、TRACE、CONNECT五種HTTP請求方法。
1.2 請求頭部
請求頭部由關鍵字/值對組成,每行一對
- User-Agent : 產生請求的瀏覽器類型
- Accept : 客戶端希望接受的數據類型,比如 Accept:text/xml(application/json)表示希望接受到的是xml(json)類型
- Content-Type:發送端發送的實體數據的數據類型。
比如,Content-Type:text/html(application/json)表示發送的是html類型。 - Host : 請求的主機名,允許多個域名同處一個IP地址,即虛擬主機
1.2.1 Content-Type
常見的Content-Type:
Content-Type | 解釋 |
---|---|
text/html | html格式 |
text/plain | 純文本格式 |
text/css | CSS格式 |
text/javascript | js格式 |
image/gif | gif圖片格式 |
image/jpeg | jpg圖片格式 |
image/png | png圖片格式 |
application/x-www-form-urlencoded | POST專用:普通的表單提交默認是通過這種方式。form表單數據被編碼為key/value格式發送到服務器。 |
application/json | POST專用:用來告訴服務端消息主體是序列化后的 JSON 字符串 |
text/xml | POST專用:發送xml數據 |
multipart/form-data | POST專用:下面講解 |
multipart/form-data
用以支持向服務器發送二進制數據,以便可以在 POST 請求中實現文件上傳等功能
現在用Postman向百度發送一個請求方式為multipart/form-data
的POST包,請求報文是這樣的:
POST / HTTP/1.1
Host: www.baidu.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 033120fe-2185-15d4-e486-75e86e2baddd
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="url"
https://www.baidu.com/
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="name"
waffle
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="desk"; filename="桌子.jpg"
Content-Type: image/jpeg
...contents of 桌子.jpg...
------WebKitFormBoundary7MA4YWxkTrZu0gW--
其中, boundary這個參數是分界線的意思,這個分界線參數具體是什么你可以隨意自定義 ,建議定義復雜一點,因為這樣子才不會跟請求體中其它字段重復。
上面的例子看出分界線=“--”+boundary
每個參數都由分界線分隔開,參數名(二進制數據還需要指明文件類型)和參數值之間有一行空行,這個空行不能省略:
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="url"
https://www.baidu.com/
消息主體最后以 --boundary-- 標示結束。
1.3 空行
請求頭之后是一個空行,通知服務器以下不再有請求頭
1.4 請求體
GET沒有請求數據,POST有。
與請求數據相關的最常使用的請求頭是 Content-Type 和 Content-Length 。
2. 響應報文
HTTP響應報文和請求報文的結構差不多,也是由四個部分組成:
<status-line> //狀態行
<headers> //消息報頭
<blank line> //空行
<response-body> //響應體
2.1 狀態行
狀態行也由三部分組成:服務器HTTP協議版本,響應狀態碼,狀態碼的文本描述
格式:HTTP-Version Status-Code Reason-Phrase CRLF
比如:HTTP/1.1 200 OK
狀態碼:由3位數字組成,第一個數字定義了響應的類別
- 1xx:指示信息,表示請求已接收,繼續處理
- 2xx:成功,表示請求已被成功接受,處理。
- 200 OK:客戶端請求成功
- 204 No Content:無內容。服務器成功處理,但未返回內容。一般用在只是客戶端向服務器發送信息,而服務器不用向客戶端返回什么信息的情況。不會刷新頁面。
- 206 Partial Content:服務器已經完成了部分GET請求(客戶端進行了范圍請求)。響應報文中包含Content-Range指定范圍的實體內容
- 3xx:重定向
-
301 Moved Permanently:永久重定向,表示請求的資源已經永久的搬到了其他位置。
-
302 Found:臨時重定向,表示請求的資源臨時搬到了其他位置
-
303 See Other:臨時重定向,應使用GET定向獲取請求資源。303功能與302一樣,區別只是303明確客戶端應該使用GET訪問
-
307 Temporary Redirect:臨時重定向,和302有着相同含義。POST不會變成GET
-
304 Not Modified:表示客戶端發送附帶條件的請求(GET方法請求報文中的IF…)時,條件不滿足。返回304時,不包含任何響應主體。雖然304被划分在3XX,但和重定向一毛錢關系都沒有
一個304的使用場景:
緩存服務器向服務器請求某一個資源的時候,服務器返回的響應報文具有這樣的字段:Last-Modified:Wed,7 Sep 2011 09:23:24,緩存器會保存這個資源的同時,保存它的最后修改時間。下次用戶向緩存器請求這個資源的時候,緩存器需要確定這個資源是新的,那么它會向原始服務器發送一個HTTP請求(GET方法),並在請求頭部中包含了一個字段:If-Modified-Since:Wed,7 Sep 2011 09:23:24,這個值就是上次服務器發送的響應報文中的最后修改時間。假設這個資源沒有被修改,那么服務器返回一個響應報文:
-
HTTP/1.1 304 Not Modified
Date:Sat, 15 Oct 2011 15:39:29
(空行)
(空響應體)
用304告訴緩存器資源沒有被修改,並且響應體是空的,不會浪費帶寬。
- 4xx:客戶端錯誤
- 400 Bad Request:客戶端請求有語法錯誤,服務器無法理解。
- 401 Unauthorized:請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用。
- 403 Forbidden:服務器收到請求,但是拒絕提供服務
- 404 Not Found:請求資源不存在。比如,輸入了錯誤的url
- 415 Unsupported media type:不支持的媒體類型
- 5xx:服務器端錯誤,服務器未能實現合法的請求。
- 500 Internal Server Error:服務器發生不可預期的錯誤。
- 503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間后可能恢復正常,