從 curl 命令行視角來講解 HTTP 請求
發送一個 HTTP 請求有很多途徑,例如瀏覽器、curl 命令行、wget 命令行等。本文將帶你從 curl 命令行視角來講解一個 http 請求中各個不同數據字段的含義
我們先來簡單講解一下 curl
命令。
curl 是一個用來請求 Web 服務器的命令行工具,-v
代表輸出通信的整個過程,-d
代表發送 一個 POST 請求並在請求正文中帶上指定數據,使用方式如下
curl -v -d 'name=hagan' http://www.hagan.zone # 使用post方式請求url並帶上數據
請求完整過程如下
hagan@hanyonggang life % curl -v -d 'name=hagan' http://www.hagan.zone
* Trying 42.193.104.246...
* TCP_NODELAY set
* Connected to www.hagan.zone (42.193.104.246) port 80 (#0)
> POST / HTTP/1.1
> Host: www.hagan.zone
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Length: 10
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 10 out of 10 bytes
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.18.0
< Date: Fri, 30 Jul 2021 01:26:20 GMT
< Content-Type: text/html
< Content-Length: 169
< Connection: keep-alive
< Location: https://www.hagan.zone/
<
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
* Connection #0 to host www.hagan.zone left intact
* Closing connection 0
本文將詳細剖析以上數據
Request
Request 代表發送請求部分,示例中 Request 部分代碼如下
hagan@hanyonggang life % curl -v -d 'name=hagan' http://www.hagan.zone
* Trying 42.193.104.246...
* TCP_NODELAY set
* Connected to www.hagan.zone (42.193.104.246) port 80 (#0)
> POST / HTTP/1.1 # [請求類型] [請求URL] [協議版本]
> Host: www.hagan.zone # 消息報頭
> User-Agent: curl/7.64.1 # 消息報頭
> Accept: */* # 消息報頭
> Content-Length: 10 # 消息報頭
> Content-Type: application/x-www-form-urlencoded # 消息報頭
>
* upload completely sent off: 10 out of 10 bytes
Request 包含三個部分,分別爲 請求行
消息報頭(Header)
請求正文(Body)
下面的講解請參考示例中 Request 部分代碼來理解。
- 請求行
請求行包含三個部分,分別爲 請求類型
請求URL
協議版本
> POST / HTTP/1.1 # [請求類型] [請求URL] [協議版本]
1. 請求類型
本次請求的請求類型爲 POST
,常見的請求類型如下
-
GET
# 請求獲取 Request-URL 所標識的資源 -
POST
# 在 Request-URL 所標識的資源後附加新的數據 -
HEAD
# 請求獲取由 Request-URL 所標識的資源的響應消息報頭 -
PUT
# 請求服務器存儲一個資源並用 Request-URL 作爲標識 -
DELETE
# 請求服務器刪除 Request-URL 所標識的資源 -
TRACE
# 請求服務器回送收到的請求消息,主要用於測試或診斷 -
CONNECT
# 保留將來使用 -
OPTIONS
# 請求查詢服務器性能、查詢資源相關選項、預檢請求
2. 請求 URL
本次請求的請求 URL 爲 /
3. 協議版本
本次請求的協議版本爲 HTTP 1.1,常見的協議版本如下
-
HTTP/1.0
-
HTTP/1.1
-
HTTP/2.0
- 消息報頭 (Header)
消息報頭有很多種字段類型,本次請求包含如下五個消息報頭
> Host: www.hagan.zone # 消息報頭
> User-Agent: curl/7.64.1 # 消息報頭
> Accept: */* # 消息報頭
> Content-Length: 10 # 消息報頭
> Content-Type: application/x-www-form-urlencoded # 消息報頭
常見的消息報頭如下
Accept
指定客戶端接受哪些類型的信息
-
text/html
# HTML 文本 -
image/gif
# gif 圖片 -
*/*
# 啥都行
Accept-Charset
客戶端接受的字符集
-
gb2312
# 中文字符 -
iso-8859-1
# 西文字符集 -
utf-8
# 多語言字符
Accept-Encoding
可接受的內容編碼
-
gzip
# 壓縮類型 -
deflate
# 壓縮類型 -
identity
# 默認
Accept-Language
指定一種自然語言
zh-cn
# 中文
Authorization
證明客戶端有權查看某個資源
Host
指定被請求資源的 Internet 主機和端口號
- hagan.zone:8080
User-Agent
用戶代理
-
操作系統及版本
-
CPU 類型
-
瀏覽器及版本
-
瀏覽器渲染引擎
-
瀏覽器語言
-
瀏覽器插件
Content-Type
Body 編碼方式
- 請求正文 (Body)
請求正文有很多種編碼方式,請求正文的類型需要根據消息報頭的Content-Type
字段來確定,本次請求的編碼方式爲application/x-www-form-urlencoded
> Content-Type: application/x-www-form-urlencoded # 消息報頭
常見的 Content-Type 類型如下
application/x-www-form-urlencoded
默認數據編碼方式
?name=hagan&age=22
application/json
序列化後的 JSON 字符串
text/xml
XML 作爲編碼方式的遠程調用規範
text/plain
數據以純文本形式進行編碼
multipart/form-data
允許 body 裏面包含多個模塊,每個模塊可以是不同類型,常用於文件上傳
需要規定一個用於分割模塊的分隔符 boundary
Content-Type: multipart/form-data; boundary=hagan # boundary爲分隔符
當指定分隔符爲 hagan
時請求體格式如下
--hagan
Content-Disposition: form-data; # name爲參數名
haganhan # 參數值 # 規範規定參數值前面必須有兩個換行符
--hagan
Content-Disposition: form-data;
Content-Type: image/png # 指定類型
<Buffer 00> # 參數值
--hagan-- # 請求體結束
整個請求體拼裝完成後 , 最後會以 -- 分隔符 -- 結尾 --hagan--
--分隔符(boundary)
Content-Disposition: form-data;
參數值1
--分隔符(boundary)
Content-Disposition: form-data;
參數值2
--分隔符(boundary)
Content-Disposition: form-data;
參數值3
--分隔符(boundary)
Content-Disposition: form-data;
Content-Type: 類型
圖片文件的二進制內容1
--分隔符(boundary)
Content-Disposition: form-data;
Content-Type: 類型
圖片文件的二進制內容2
--分隔符(boundary)
Content-Disposition: form-data;
Content-Type: 類型
圖片文件的二進制內容3
--分隔符(boundary)--
application/octet-stream
只能通過流的方式提交一個二進制或文件
Response
Response 代表服務端響應部分,示例中 Response 部分代碼如下
< HTTP/1.1 301 Moved Permanently # 狀態行 # [協議版本] [狀態碼] [狀態信息]
< Server: nginx/1.18.0 # 響應報頭
< Date: Fri, 30 Jul 2021 01:26:20 GMT # 響應報頭
< Content-Type: text/html # 實體報頭
< Content-Length: 169 # 實體報頭
< Connection: keep-alive # 實體報頭
< Location: https://www.hagan.zone/ # 響應報頭
<
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
* Connection #0 to host www.hagan.zone left intact
* Closing connection 0
Response 也包含三個部分,分別爲 狀態行
消息報頭(Header)
響應正文(Body)
,下面將詳細講解這三部分。
下面的講解請參考示例中 Response 部分代碼來理解。
- 狀態行
狀態行包含三個部分,分別爲 協議版本
狀態碼
狀態信息
< HTTP/1.1 301 Moved Permanently # 狀態行 # [協議版本] [狀態碼] [狀態信息]
1. 協議版本
本次響應的協議版本爲 HTTP/1.1
,常見協議版本如下
-
HTTP/1.0
-
HTTP/1.1
-
HTTP/2.0
2. 狀態碼
本次響應的狀態碼爲 301
,常見狀態碼如下
1xx
指示信息,表示請求已接收,繼續處理
2xx
成功,表示請求已被成功接收、理解、接受
-
200
OK,請求成功 -
201
Created,對於那些要服務器創建對象的請求來說,資源已創建完畢 -
202
Accepted,請求已接受,但服務器尚未處理 -
204
No Content,Response 包含狀態行和消息報頭,但不包含響應正文 -
206
Partial Content,部分請求成功
3xx
重定向,要完成請求必須進行更進一步的操作
-
301
請求永久重定向至新 URL -
302
請求臨時重定向至新 URL
4xx
客戶端錯誤。請求有語法錯誤或請求無法實現
-
400
Bad Request,錯誤的請求 -
401
Unauthorized,需要客戶端認證 -
403
Forbidden,請求被服務器拒絕 -
404
Not Found,未找到資源
5xx
服務端錯誤,服務端未能實現合法的請求
-
500
Internal Server Error,內部服務器錯誤 -
503
Server Unavailable,服務器暫時無法提供服務,一段時間後便可恢復服務
3. 狀態信息
本次響應的狀態信息爲 Moved Permanently
,常見狀態信息如下
-
OK
-
Moved Permanently
-
Not Found
- 消息報頭 (Header)
Response 中的消息報頭主要分爲 響應報頭
和 實體報頭
響應報頭
本次響應中的響應報頭包含如下三個
< Server: nginx/1.18.0 # 響應報頭
< Date: Fri, 30 Jul 2021 01:26:20 GMT # 響應報頭
< Location: https://www.hagan.zone/ # 響應報頭
常見的響應報頭如下
Location
重定向接受者到一個新的位置
WWW- Authenticate
包含在 401 響應消息中,客戶端收到 401
Server
包含了服務器用來處理請求的軟件信息
Apache- Coyote/1.1
實體報頭
實體報頭也叫正文報頭,本次響應中的實體報頭包含如下三個
< Content-Type: text/html # 實體報頭
< Content-Length: 169 # 實體報頭
< Connection: keep-alive # 實體報頭
常見的實體報頭如下
Content-Encoding
編碼類型是壓縮還是非壓縮
eg: Content-Encoding: gzip
Content-Language
資源所用的自然語言,沒有設置該域則認爲實體內容將提供給所有的語言閱讀
Content-Length
正文的長度,以字節方式存儲的十進制數字表示
Content-Type
響應正文的媒體類型
- 實體類型列表
Expires
響應過期的日期和時間
- 響應正文 (Body)
響應正文有很多種類型,響應正文的類型需要根據消息報頭的Content-Type
字段來確定,本次響應的編碼方式爲text/html
< Content-Type: text/html # 實體報頭
響應正文如下
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
* Connection #0 to host www.hagan.zone left intact
* Closing connection 0
curl 命令只展示數據,不提供數據的解析,如果是瀏覽器,則會將響應正文以 text/html
的方式進行解析,此時便得到了一個 HTML 頁面
本文會在我的博客持續更新,歡迎訪問我的博客 hagan.zone
,也可點擊閱讀原文直接跳轉到文章詳情頁,裏面會包含我最新的修改。
參考資料
- http://www.ruanyifeng.com/blog/2019/09/curl-reference.html
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/9wiLgpvFB2OpkWEHgj40hw