HTTP 的全稱是 HyperText Transfer Protocol (超文本傳輸協議)的縮寫,是一種創建在 TCP 上的無狀態鏈接。HTTP 是互聯網的基礎協議,用於客戶端與服務器之間的通訊,它規定了客戶端和服務器之間的通訊格式,包括請求與響應的格式。html
基本的工做流程是客戶端發送一個 HTTP 請求,服務端收到請求開始處理,處理結束返回給客戶端結果,客戶端對結果進行處理並展現。node
如今最流行的 HTTP 版本仍是 1997 年發佈的 HTTP/1.1。 git
客戶端向服務端發送一段請求報文,服務端收到後,返回響應報文,客戶端對響應內容進行展現。github
一個 HTTP 的請求一定是由客戶端發起,服務器端回覆響應。服務器在沒有接收到請求以前不會發送響應。web
名詞解釋算法
客戶端:請求訪問文本或圖像等資源的一端。json
服務端:提供資源響應的一端。api
資源:網絡上的一切內容都是資源,不管是圖片文字仍是動態代碼。瀏覽器
請求過程以下 ⬇️緩存
請求過程以下 ⬇️
報文是在 HTTP 應用程序之間發送的數據塊。這些數據塊以一些文本的元信息 (meta 標籤中的信息) 開頭,描述了報文的內容及含義。
每條報文都包含一條來自於客戶端的請求,或者一條來自於服務端的響應。
它由 3 部分組成:對報文進行描述的「起始行」、包含屬性的「首部(Header)」以及可選的、包含數據的「主體(body)」
<method> <path> <HTTP version>
<headers>
<entity-body>
複製代碼
(注意,只有起始行的語法與請求報文有所不一樣)
<HTTP version> <status code> <reason-phrase>
<headers>
<entity-body>
複製代碼
下面是對各部分的簡要描述,後面會詳細介紹。
最多見的請求方法就是 GET
和 POST
了。除此以外還有 PUT
、DELETE
、HEAD
等。
GET /users/1 HTTP/1.1
Host: api.github.com
複製代碼
對應的 Retrofit 的代碼:
@GET("/users/{id}")
Call<User> getUser(@Path("id") String id, @Query("gender") String gender);
複製代碼
POST /users HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
複製代碼
對應的 Retrofit 的代碼:
@FormUrlEncoded
@POST("/users")
Call<User> addUser(@Field("name") String name, @Field("gender") String
gender);
複製代碼
PUT /users/1 HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
複製代碼
對應的 Retrofit 的代碼:
@FormUrlEncoded
@PUT("/users/{id}")
Call<User> updateGender(@Path("id") String id, @Field("gender") String
gender);
複製代碼
DELETE /users/1 HTTP/1.1
Host: api.github.com
複製代碼
對應的 Retrofit 的代碼:
@DELETE("/users/{id}")
Call<User> getUser(@Path("id") String id, @Query("gender") String gender);
複製代碼
HEAD
與 GET
的使用方式徹底相同。HEAD
請求的返回響應中沒有 Body
GET
、PUT
、DELETE
都是冪等操做,就是說,請求一次和請求屢次的結果是同樣的。 好比,GET 請求一個數據,請求一次和請求十次返回的結果是同樣的,PUT 一樣修改一個數據,修改一次和修改十次,結果也都是同樣的。
狀態碼是對結果進行類型化的描述的,好比「請求成功」、「內容未找到」等 主要分爲 5 類。
100:繼續發送
101:正在切換協議
複製代碼
200:OK (最多見)
201:建立成功
複製代碼
301:域名永久移動
302:暫時移動
304:內容未改變,請求被重定向到客戶端本地緩存
複製代碼
400:客戶端請求錯誤,服務器不理解請求的語法。
401:未受權,要求進行身份驗證。
403:被禁止,服務器拒絕請求。
404:找不到內容,服務器找不到請求的網頁。(最多見)
複製代碼
500:服務器內部錯誤 (最多見)
503:服務不可用
複製代碼
首部包含多個請求頭,是用來描述消息的元數據(meta data)。
首部字段有不少,主要分爲如下幾類:
下面咱們就說一些比較經常使用的。
提供日期和時間標誌,說明報文是在什麼時間建立的。
Date: Tue, 12 Feb 2019 07:32:07 GMT
複製代碼
容許客戶端和服務器指定與請求/響應鏈接有關的選項。
Connection: keep-alive
複製代碼
Via : 顯示報文通過的中間節點(代理、網關)。
via: cache25.l2ot7-1[0,304-0,H], cache25.l2ot7-1[1,0], cache5.us14[342,200-0,H]
複製代碼
Transfer-Encoding : 告知接收端爲了保證報文的可靠傳輸,對報文采用了什麼編碼方式。
Transfer-Encoding: chunked
複製代碼
Cache-Control : 指定緩存的控制方式。
cache-control: no-store, no-cache, must-revalidate, proxy-revalidate
複製代碼
給出了接收請求的服務器的主機名和端口。(注意:不是在網絡上用於尋址的,⽽是在目標服務器上定位子服務器。)
Host: api.github.com
複製代碼
用來告訴服務端客戶端會接受的媒體類型,包括客戶端須要什麼,可使用什麼,以及不想要什麼。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
'*' 用來表示通配符。
;q= (q-factor weighting)
值表明優先順序,用相對質量價值表示,又稱爲權重。
複製代碼
用來告知服務器,客戶端能夠處理的字符集類型。
Accept-Charset: utf-8, iso-8859-1;q=0.5
複製代碼
用來將客戶端可以理解的內容編碼方式告知服務器,服務端會選擇一個客戶端提議的方式。
Accept-Encoding: gzip, deflate, br
gzip:表示採用 Lempel-Ziv coding (LZ77) 壓縮算法,以及32位CRC校驗的編碼方式。
compress:採用 Lempel-Ziv-Welch (LZW) 壓縮算法。
deflate:採用 zlib 結構和 deflate 壓縮算法。
br:表示採用 Brotli 算法的編碼方式。
identity:用於指代自身(例如:未通過壓縮和修改)。除非特別指明,這個標記始終能夠被接受。
複製代碼
用來告訴服務器,客戶端可以理解哪些語言
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
複製代碼
告訴服務器,客戶端要獲取哪段數據。 主要用於:斷點續傳、多線程下載。
語法:
Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
<unit>:範圍所採用的單位,一般是字節(bytes)。
<range-start>:一個整數,表示在特定單位下,範圍的起始值。
<range-end>:一個整數,表示在特定單位下,範圍的結束值。這個值是可選的,若是不存在,表示此範圍一直延伸到文檔結束。
Range: bytes=200-1000, 2000-6576, 19000-
複製代碼
提供了客戶端用戶的 E-mail 地址, 用處:好比你有一個爬蟲程序,那麼 Form 首部應該隨請求一塊兒發送,這樣的話,在服務器遇到問題的時候,例如爬蟲發送了過量的、不但願收到的或者不合法的請求時,站點管理員能夠聯繫到你。
包含了處理請求的源頭服務器所用到的軟件相關信息
Server: Apache-Coyote/1.1
複製代碼
用來由服務器端向客戶端發送 cookie。
會話期 cookies 將會在客戶端關閉時被移除。
會話期 cookie 不設置 Expires 或 Max-Age 指令
Set-Cookie: sessionid=38afes7a8; HttpOnly; Path=/
持久化 Cookie 不會在客戶端關閉時失效,而是在特定的日期(Expires)或者通過一段特定的時間以後(Max-Age)纔會失效。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
複製代碼
響應中出現,表示服務器支持按字節來取範圍數據
語法:
Accept-Ranges: bytes
Accept-Ranges: none
none:不支持任何範圍請求單位,因爲其等同於沒有返回此頭部,所以不多使用。
bytes:範圍請求的單位是 bytes (字節)。
Accept-Ranges: bytes
複製代碼
因爲請求與響應中均可以包含 body部分,因此在請求報文與響應報文中均可以出現這部分字段。
指定的是須要將頁面從新定向至的地址。通常在響應碼爲 3xx 的響應中才會有意義。
Location: /index.html
複製代碼
告訴客戶端實際返回的內容的內容類型。 主要分爲 4 類。
請求 Web ⻚面時返回響應的類型,Body 中返回 html 文本。
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 853
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
複製代碼
Web ⻚面純⽂本表單的提交方式
POST /users HTTP/1.1
Host: api.github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
name=xxtlant&gender=male
複製代碼
Web ⻚面含有⼆制⽂件時的提交方式。
POST /users HTTP/1.1
Host: hencoder.com
Content-Type: multipart/form-data; boundary=----
WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 2382
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="name"
rengwuxian
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="avatar"; filename="avatar.jpg"
Content-Type: image/jpeg
JFIFHHvOwX9jximQrWa......
------WebKitFormBoundary7MA4YWxkTrZu0gW--
複製代碼
單項內容(⽂本或非⽂本均可以),用於 Web Api 的響應或者 POST / PUT 的請求。
請求中提交 JSON
POST /users HTTP/1.1
Host: api.github.com
Content-Type: application/json; charset=utf-8
Content-Length: 38
{"name":"xxtlant","gender":"male"}
複製代碼
響應中返回 JSON
Date: Tue, 12 Feb 2019 08:04:14 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Server: GitHub.com
Status: 200 OK
{"login": "xxtlant",
"id": 18342980,
"node_id": "MDQ6VXNlcjE4MzQyOTgw",
"avatar_url": "https://avatars2.githubusercontent.com/u/18342980?v=4",
"gravatar_id": "",
....
複製代碼
請求中提交⼆進制內容
POST /user/1/avatar HTTP/1.1
Host: hencoder.com
Content-Type: image/jpeg
Content-Length: 1575
JFIFHH9......
複製代碼
相應中返回⼆進制內容
HTTP/1.1 200 OK
content-type: image/jpeg
content-length: 1575
JFIFHH9......
複製代碼
用來指明發送給接收方的消息主體的大小。
Content-Length: <length>
複製代碼
用於對特定媒體類型的數據進行壓縮。 這個消息用來告知客戶端應該怎樣解碼才能獲取在 Content-Type 中的媒體類型內容。
Content-Encoding: gzip
其值受 Accept-Encoding 影響
複製代碼
與此對應,Content-Language 也與 Accept-Language 對應。