一、介紹
HTTP 即超文本傳輸協議,它規定了數據在網絡中傳輸的格式,HTTP 在應用層將數據封裝成固定的格式,然后再交由傳輸層去進行傳輸。如下圖所示:
二、HTTP 報文格式
HTTP 協議是用戶客戶端和服務器之間的通信的,其報文格式分為 客戶端 的 請求報文,服務器 的 響應報文 ,兩者的通用構成是:
啟始行 + 頭部(首部字段) + 空行 + 實體
而 請求報文 和 響應報文 兩者又有所區別:
請求報文:
請求報文由四部分組成:
請求行 + 請求頭(請求首部字段) + 空行 + 實體
1、請求行
請求行里面有 請求方法(如 GET 、POST),資源對象(URI),協議名稱和版本號(HTTP/1.1),具體的例子:
POST /custom/a2873925c34ecbd2/web/cstm?stm=1649149234039 HTTP/1.1、
POST 即請求方法
/custom/a2873925c34ecbd2/web/cstm?stm=1649149234039 即 URI 資源地址
HTTP/1.1 即協議和版本
2、請求頭(請求首部字段)
請求首部字段主要是告訴服務器這個請求的一些信息,起到傳遞額外信息的目的。如:
Host: api.growingio.com //主機 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Firefox/91.0 //采用的系統 Accept: */* Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate, br Content-Length: 264 Origin: https://leetcode-cn.com Sec-Fetch-Dest: empty Sec-Fetch-Mode: no-cors Sec-Fetch-Site: cross-site Referer: https://leetcode-cn.com/
3、空行
空行是為了區分 請求頭 和 請求實體。
4、請求實體
請求實體即真正所需要傳輸的數據
響應報文:
響應報文同樣是由四部分組成:
狀態行 + 響應頭 + 空行 + 消息體
1、狀態行
狀態行主要由三部分組成:HTTP版本、狀態碼(表示相應的結果)、原因短語(解釋)。例如:
HTTP/2 200 OK
HTTP/2 協議和版本
200 狀態碼(具體后面詳解)
OK 原因短語
2、響應頭(響應報文首部)
和請求報文首部一樣,響應報文首部同樣是為了傳遞額外信息,例如:
date: Tue, 05 Apr 2022 10:48:17 GMT //響應時間 content-type: application/json //響應格式 content-length: 127 //長度 strict-transport-security: max-age=31536000 X-Firefox-Spdy: h2
3、空行
同樣是為了區別 響應實體 和 響應首部
4、響應實體
真正存儲響應信息的部分
三、深入HTTP
URI
URI 稱為統一資源定位符,用於區分互聯網中不同的資源,但 URI 不是我們常說的網址,URI 還可以分為 URL 和 URN,由於 URL 的普及,所以也將 URL 稱為統一資源定位符。
URI的結構:
scheme:表示協議名,比如http
, https
, file
等等。后面必須和://
連在一起。
user: passwd@ 表示登錄主機時的用戶信息,不過很不安全,不推薦使用,也不常用。
host: port表示主機名和端口。
path: 表示請求路徑,標記資源所在位置。
query: 表示查詢參數,為key=val
這種形式,多個鍵值對之間用&
隔開。
fragment:表示 URI 所定位的資源內的一個錨點,瀏覽器可以根據這個錨點跳轉到對應的位置。
響應報文的狀態碼詳解
在客戶端發送請求報文給服務器后,服務器會發送響應報文,響應報文中頭部狀態行中有一個十分重要的標識就是狀態碼,原來表示服務器對客戶端的響應結果,如 200 就代表響應成功,這里的狀態碼可以分為幾類:
狀態碼的第一位數字定義響應的類別。 后兩位數字沒有任何分類作用。可以分為5個類別:
- 1xx:信息狀態碼,收到請求,繼續進行;
- 2xx:請求成功接收;
- 3xx:重定向,必須采取進一步措施才能完成請求;
- 4xx:客戶端錯誤,請求包含錯誤語法,或者不能被完成;
- 5xx:服務器錯誤,服務器無法完成看似有效的請求;
狀態碼 | 描述 | 詳細說明 |
---|---|---|
101 | Switching Protocol | 該代碼是響應客戶端的 Upgrade 標頭發送的,並且指示服務器也正在切換的協議。 |
200 | OK | 請求成功。 |
204 | No Content | 服務器成功處理了請求,但不需要返回任何實體內容,並且希望返回更新了的元信息。 用這個狀態碼區分成功狀態下又返回內容和沒返回內容的響應。 |
206 | Partial Content | 服務器已經成功處理了部分 GET 請求。通過HTTP的分塊下載,獲取資源的部分時返回。該請求必須包含 Range 頭信息來指示客戶端希望得到的內容范圍,並且可能包含 If-Range 來作為請求條件。 206狀態碼通常會攜帶 Content-Range ,用於表示報文里面body數據的具體范圍。 |
301 | Moved Permanently | 永久重定向,將來任何對此資源的引用都應該使用本響應返回的若干個 URI 之一。 |
302 | Found | 臨時重定向,客戶端下次應當繼續向原有地址發送以后的請求。只有在Cache-Control或Expires中進行了指定的情況下,這個響應才是可緩存的。 |
304 | Not Modified | 如果客戶端發送了一個帶條件的 GET 請求且該請求已被允許,而文檔的內容(自上次訪問以來或者根據請求的條件)並沒有改變,則服務器應當返回這個狀態碼。304 響應禁止包含消息體,因此始終以消息頭后的第一個空行結尾。 |
400 | Bad Request | 語義有誤,當前請求無法被服務器理解。除非進行修改,否則客戶端不應該重復提交這個請求。 |
401 | Unauthorized | 當前請求需要用戶驗證。該響應必須包含一個適用於被請求資源的 WWW-Authenticate 信息頭用以詢問用戶信息。客戶端可以重復提交一個包含恰當的 Authorization 頭信息的請求。 |
403 | Forbidden | 服務器已經理解請求,但是拒絕執行它。如果這不是一個 HEAD 請求,而且服務器希望能夠講清楚為何請求不能被執行,那么就應該在實體內描述拒絕的原因。當然服務器也可以返回一個 404 響應,假如它不希望讓客戶端獲得任何信息。 |
404 | Not Found | 請求失敗,請求所希望得到的資源未被在服務器上發現。 究竟是不是真的資源不存在呢?還得看程序是怎么寫的。 |
405 | Method Not Allowed | 請求行中指定的請求方法不能被用於請求相應的資源。該響應必須返回一個Allow 頭信息用以表示出當前資源能夠接受的請求方法的列表。 |
408 | Request Timeout | 請求超時。客戶端沒有在服務器預備等待的時間內完成一個請求的發送。客戶端可以隨時再次提交這一請求而無需進行任何更改。 |
409 | Conflict | 由於和被請求的資源的當前狀態之間存在沖突,請求無法完成。 |
413 | Payload Too Large | 請求提交的實體數據大小超過了服務器願意或者能夠處理的范圍。此種情況下,服務器可以關閉連接以免客戶端繼續發送此請求。如果這個狀況是臨時的,服務器應當返回一個 Retry-After 的響應頭,以告知客戶端可以在多少時間以后重新嘗試。 |
429 | Too Many Requests | 用戶在給定的時間內發送了太多請求(“限制請求速率”)。 |
431 | Request Header Fields Too Large | 請求頭字段太大( Request Header Fields Too Large) |
500 | Internal Server Error | 服務器遇到了不知道如何處理的情況。通常用來捕獲服務器異常,統一返回500,避免輸出詳細錯誤堆棧給別人利用。 |
501 | Not Implemented | 此請求方法不被服務器支持且無法被處理。只有GET 和HEAD 是要求服務器支持的,它們必定不會返回此錯誤代碼。 |
502 | Bad Gateway | 此錯誤響應表明服務器作為網關需要得到一個處理這個請求的響應,但是得到一個錯誤的響應。 |
503 | Service Unavailable | 服務器沒有准備好處理請求。 常見原因是服務器因維護或重載而停機。 |
504 | Gateway Timeout | 當服務器作為網關,不能及時得到響應時返回此錯誤代碼。 |