未完全完成,先發出來再說。
HTTP(Hypertext Transfer Protocol,超文本傳輸協定)是應用層的無狀态的請求和響應協定。它使得基于網絡的超文本資訊系統彼此可以靈活地進行互動。它包含了可拓展的語義(extensible semantics)和自描述的有效封包載荷(self-descriptive message payloads)。
-
應用層:OSI 七層模型的頂層;
定義請求頭;
- 自描述的:指封包本身描述了處理這個封包的方式,例如 HTML 最開始的
;<!DOCTYPE
- 有效封包載荷:真正需要的資料,HTML 内容或者 JSON 串;
- 注:從表示上看,像解釋型語言(與編譯型語言相對)。其内容可以被所有程式設計語言處理,是以不受限于特定程式設計語言和特定平台。基于不同程式設計語言的系統可以通過 HTTP 進行互動。
曆史
最早對 HTTP/1.1 做出說明的 RFC 文檔是 1997 年釋出的 RFC2068。在 1999 年釋出的 RFC2616 對 RFC2068 做了更新。
目前關于 HTTP/1.1 最新的文檔是 2014 年釋出的 RFC7230、RFC7231、RFC7232、RFC7233、RFC7234、RFC7235 ,它們将 RFC2616 的内容拆分開來并做詳細的解釋與更新。
在 RFC INDEX 頁面可以看到它們之間的關系:
https://www.rfc-editor.org/rfc-index.html
2068 Hypertext Transfer Protocol -- HTTP/1.1 R. Fielding, J. Gettys, J. Mogul, H. Frystyk, T. Berners-Lee [ January 1997 ] (TXT, HTML) (Obsoleted-By RFC2616) (Status: PROPOSED STANDARD) (Stream: IETF, Area: app, WG: http) (DOI: 10.17487/RFC2068)
2616 Hypertext Transfer Protocol -- HTTP/1.1 R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee [ June 1999 ] (TXT, PS, PDF, HTML) (Obsoletes RFC2068) (Obsoleted-By RFC7230, RFC7231, RFC7232, RFC7233, RFC7234, RFC7235) (Updated-By RFC2817, RFC5785, RFC6266, RFC6585) (Status: DRAFT STANDARD) (Stream: IETF, Area: app, WG: http) (DOI: 10.17487/RFC2616)
7230 Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing R. Fielding, J. Reschke [ June 2014 ] (TXT, HTML) (Obsoletes RFC2145, RFC2616) (Updates RFC2817, RFC2818) (Updated-By RFC8615) (Status: PROPOSED STANDARD) (Stream: IETF, Area: app, WG: httpbis) (DOI: 10.17487/RFC7230)
具體的内容見:
- https://tools.ietf.org/html/rfc2068:過時的
- https://tools.ietf.org/html/rfc2616:過時的
- https://tools.ietf.org/html/rfc7230
- https://tools.ietf.org/html/rfc7231
- https://tools.ietf.org/html/rfc7232
- https://tools.ietf.org/html/rfc7233
- https://tools.ietf.org/html/rfc7234
- https://tools.ietf.org/html/rfc7235
内容
本文會對 RFC7230-7235 的内容做個大概的說明(翻譯),并且在必要的時候做詳細說明(翻譯)。
-
RFC7230:文法和路由
文法:描述了一個 HTTP 請求或者響應長什麼樣。即第一行寫什麼怎麼寫、第二行寫什麼怎麼寫...
路由:資源辨別(URI)如何确定?通過什麼方式擷取到想要的内容?是直接從本地緩存擷取?還是通過代理(Proxy)擷取?還是直接請求?
-
RFC7231:語義和内容(最需要關注的内容,RESTful-like)
各種請求方法(GET、POST、DELETE 等等)和請求頭(Expect、Accept-Language、User-Agent 等等)表達了什麼意圖?
響應體的狀态(200 OK、201 Created、403 Forbidden 等等)和響應頭(Location、Retry-After、Allow 等等)表達什麼意思?
-
RFC7232:條件請求
響應體告知用戶端某些資料條件(Last-Modified、ETag 等等),用戶端可以在下次請求的時候帶上這些資訊(If-Modified-Since、If-Match 等等)。在符合條件或者不符合條件的情況下,服務端應該如何處理;
-
RFC7233:範圍請求
由于各種因素而隻得到部分響應的時候,發起範圍請求以擷取剩下的内容,避免從頭請求而浪費資源;
-
RFC7234:緩存
通過減少請求避免網絡資源的浪費;
-
RFC7235:認證
使用者認證。Basic Auth、Token 等等。
用戶端和服務端
用戶端發起連接配接請求給服務端,服務端接收來自用戶端的請求,并建立連接配接。
使用者代理(User Agent)
用于表示各種用戶端程式,例如浏覽器、爬蟲、指令行工具、手機應用等等。
源伺服器(Origin Server)
用于表示對用戶端請求的資源生成一個權威性的響應的程式。
HTTP 通過 URI 确定目标資源和資源間的關系。
請求的文法
例子:
GET /hello.txt HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Host: www.example.com
Accept-Language: en, mi
- 第 1 行(請求行)包含三個資訊:請求方法、URI、HTTP 版本
- 第 2-4 行是請求頭(Headers)
- 請求頭以一個空行作為結束标志
- 在空行後面是真正想要發送的封包——有效載荷體(payload body),如果沒有就放空。
響應的文法
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain
Hello World! My payload includes a trailing CRLF.
- 第 1 行(狀态行)包含三個資訊:HTTP 版本、狀态碼、原因
- 第 2-9 行是響應頭(Header)
- 響應頭以一個空行作為結束标志
- 在空行後面是用戶端想要的封包——有效載荷體(payload body),如果沒有就放空。
中轉(Intermediaries)
從 User Agent 到 Origin Server,中間可以經過各種中轉。中轉通常有三種:代理(Proxy)、網關(Gateway)和隧道(Tunnel)。
> > > >
UA =========== A =========== B =========== C =========== O
< < < <
-
入站(Inbound)和出站(Outbound)
入站表示朝向源伺服器,出站表示朝向使用者代理。
-
代理(Proxy)
一種由用戶端選擇的封包轉發代理(message-forwarding agent)。按照一定規則讓請求通過同一個中轉。
-
網關(Gateway)
又稱為反向代理(Reverse Proxy)。對于出站連接配接來說,網關就像是源伺服器。經常被用于攔截不被信任的服務、提高伺服器性能、負載均衡等等。
-
隧道(Tunnel)
通常被用于建立一條虛拟的連接配接。通過這條連接配接的封包不會發生變化。
-
透明代理(Transparent Proxy)
不是由用戶端選擇的代理。例如在路由器上建立代理,電腦的浏覽器感覺不到這個代理。
無狀态
HTTP 是無狀态的協定。這意味着每個請求都能夠被獨立地了解。
但是由于代理會複用連接配接或者動态負載均衡的存在,服務端不應該認為來自同一條連接配接的請求來自于同一個使用者代理(User Agent)。
緩存
緩存用于存放先前的響應封包,它還作為子系統管理着緩存的抽取和删除。
使用緩存的目的是減少未來發起與先前等價的請求時所帶來的響應耗時和網絡帶寬的消耗。
> >
UA =========== A =========== B - - - - - - C - - - - - - O
< <
在 B 緩存了先前的響應封包後,UA 發出的請求就不必再經過 C 和 O 了。
一個響應是否會被緩存,由多個因素決定。在 RFC7234 裡有詳細的說明。
協定版本
格式是:
<major>.<minor>
但從 HTTP/2 開始,僅保留 major 。例如 HTTP/3。
https://www.ruanyifeng.com/blog/2016/08/http.html
RFC7231:語義和内容
請求方法
請求方法表明用戶端發起請求的目的,以及用戶端所預期的成功結果。
Representation (表征):
the way that someone or something is shown or described.
人或物被展示或者描述的方式。
+---------+-------------------------------------------------+-------+
| Method | Description | Sec. |
+---------+-------------------------------------------------+-------+
| GET | 傳輸目标資源的一種表征 | 4.3.1 |
| HEAD | 和 GET 相同,但隻傳輸狀态和頭部 | 4.3.2 |
| POST | 執行請求有效載荷中特定于資源的處理 | 4.3.3 |
| PUT | 用請求有效載荷替換資源的所有表征 | 4.3.4 |
| DELETE | 删除目标資源的所有表征 | 4.3.5 |
| CONNECT | 建立一條與目标資源指定的伺服器之間的隧道 | 4.3.6 |
| OPTIONS | 描述與目标資源相關的選項 | 4.3.7 |
| TRACE | 執行一個沿着用戶端到目标資源路徑的消息回送測試 | 4.3.8 |
+---------+-------------------------------------------------+-------+
這些方法可以按照不同屬性分類:
-
安全(safe)和非安全(unsafe)
安全的方法不會造成目标資源的狀态改變。方法包括 GET/HEAD/OPTIONS/TRACE。
-
幂等(idempotent)
同一個請求執行一次或者多次,對服務端資源的影響是一緻的。
幂等的方法包括所有的安全方法,還有 PUT/DELETE。例如多次 DELETE 同一個資源,對于服務端來說,最終的結果都是該資源不存在。執行一次或者執行多次都一樣。
幂等容易被誤解為對用戶端來說的幂等,導緻難以了解為什麼 GET 也是幂等的:畢竟每次 GET 傳回的結果都可能不一樣。是以要注意站在服務端資源的角度來看。
-
可緩存(cacheable)
響應結果可存儲起來供後續使用。方法包括 GET/HEAD/POST。
大多數的緩存實作都隻實作 GET/HEAD,但 RFC 7231 多定義了一個 POST。
這部分内容在 RFC 7234 有詳細介紹。
方法定義
GET
HEAD
POST
POST 根據結果選擇合适的狀态碼:
-
201 Created
一個或多個資源建立成功後,傳回該狀态碼。同時要在頭部加上 Location,指向建立的主要資源。
- 206 Partial Content
-
303 See Other
如果 POST 的處理結果與一個已存在資源的某一種表征一緻,那麼服務端在處理完 POST 後,可以用 303 重定向到已存在的資源。
這是為了共享緩存,但如果用戶端代理之前沒有緩存該已存在資源的表征,則會因為 303 而額外地發起一次請求。
- 304 Not Modified
- 416 Range Not Satisfiable
PUT
服務端應校驗服務端對目标資源的配置,例如内容的類型。
PUT 根據結果選擇合适的狀态碼:
-
200 OK
目标資源已存在,此次更新成功
- 目标資源先前不存在,此次執行建立了該資源。
- 204 No Content
-
400 Bad Request
用戶端請求頭包含 Content-Range。部分更新應使用 PATCH。
- 409 Conflict
-
415 Unsupported Media Type
服務端對資源配置的 Content-Type 與用戶端配置的不一緻。例如服務端限定隻能是
,而用戶端在 HTTP 頭部配置的是text/html
image/jpeg
。
這隻是一種處理方式,其他兩種處理方式為:
- 服務端将用戶端傳輸的類型轉換為服務端配置的類型,然後存儲
- 服務端變更配置,将 Content-Type 配置為用戶端設定的類型
DELETE
DELETE 表達的是源伺服器 URL 映射的一種删除操作,而不是一種删除先前關聯資訊的期望。和 rm 指令類似,隻删除映射,并沒有将資料清除。
一個資源如果有一種或者多種表征,源伺服器可以選擇是否清除資料,也可以選擇是否回收資料的存儲空間。
當使用 PUT 建立資源和 POST 建立資源後,可以用 DELETE 來撤銷(undo)這些操作。
DELETE 根據結果選擇合适的狀态碼:
- 操作成功,且響應體包含了描述結果的資訊
-
202 Accepted
操作很可能成功,但還未執行或者還未執行完成。
- 操作成功,且不需要傳回更多的資訊給用戶端
由于删除操作是幂等的,是以多次删除同一個資源讓源伺服器對于該資源處于同一個狀态。
OPTIONS
OPTIONS 用于擷取目标資源所支援的選項。OPTIONS 沒有對目标資源做出修改。
OPTIONS 支援兩種資源類型:
-
用于類似 ping 或者空操作。*
- 非
用于擷取可用的适用于目标資源的選項。*
服務端在生成響應的時候,應該發送服務端實作的适用于目标資源的任何可選特性的頭部。例如 Allow。此外還包括潛在的沒有定義在 RFC 7221 的擴充。
OPTIONS 響應允許包含響應體,用于描述通信選項。如果不包含響應體,其 Content-Length 必須設定為 0。
OPTIONS 請求允許包含請求體。此時請求頭必須包含 Content-Type 頭部描述請求體的媒體類型。
CONNECT
CONNECT 用于建立從參與者到源伺服器之間的通道。
TRACE
TRACE 請求應用層級别的回環
請求頭字段
起控制作用的請求頭
+-------------------+
| Header Field Name |
+-------------------+
| Cache-Control |
| Expect |
| Host |
| Max-Forwards |
| Pragma |
| Range |
| TE |
+-------------------+
-
Max-Forwards
隻用于 TRACE 和 HEAD 請求方法。它的值是一個十進制整數,用于表示代理剩餘可轉發次數。
起條件作用的請求頭(RFC 7232)
+---------------------+
| Header Field Name |
+---------------------+
| If-Match |
| If-None-Match |
| If-Modified-Since |
| If-Unmodified-Since |
| If-Range |
+---------------------+
服務端響應一個資源的時候,可以包含響應專用的 ETag 和 Modified-Since 兩個響應頭,表示資源的版本。
用戶端可以在後續請求時,将 ETag 的值放在 If-Match 或者 If-None-Match 上,将 Modified-Since 的值放在 If-Modified-Since 或者 If-Unmodified-Since 上。
-
If-Match
If-Match 的值可以加雙引号,值可以有多個,多個值用逗号隔開。值還可以是
,表示比對任意 ETag,但如果一個都沒有的時候,為 false。比對方式使用強比對。*
- 當用戶端要更新一個資源,使用了 If-Match 頭,它要求目前服務端該資源的 ETag 應該是剛才 GET 資源時所獲得的 ETag。避免覆寫掉其他請求對該資源的更新,或者避免更新請求的響應丢失時重試。
- 當 If-Match 用于安全的請求方法(如 GET)時,如果服務端資源的 ETag 與之不比對,則終止該請求。
- If-None-Match
- 使用弱比對。
- 如果用戶端要初始化一個資源,使用了 If-None-Match 頭,它要求目前資源的 ETag 不是剛才獲得的 ETag 才能更新。例如将 If-None-Match 設定為
,避免多個初始化請求時後者覆寫前者。*
- 當 If-None-Match 為 false 時:
- 如果使用 GET 或者 HEAD,傳回 304 Not Modified
- 如果使用其他請求方法,則傳回 412 Precondition Failed
-
If-Modified-Since
如果請求頭還包含 If-None-Match,則忽略 If-Modified-Since
如果服務端發現資源的最後一次修改時間早于或者等于 If-Modified-Since 指定的時間,則不執行操作而是傳回 304 Not Modified
-
If-Unmodified-Since
如果請求頭還包含 If-Match,則忽略 If-Unmodified-Since
避免覆寫其他的修改
如果服務端發現資源的最後一次修改時間晚于 If-Modified-Since 指定的時間,則不執行操作,傳回 412 Precondition Failed 或者 2xx。傳回 2xx 的場景是請求的操作給資源帶來的最終狀态與目前狀态一緻。
如果用戶端使用 GET 或者 HEAD 時,想要通過請求頭來嘗試命中緩存,則應該使用以下兩個請求頭:
- If-None-Match 表示 “如果不比對該 ETag,則傳回最新的資料”。如果響應的狀态碼是 304 Not Modified ,則表示用戶端傳送的 ETag 與服務端的一緻。
- If-Modified-Since 表示 “這個時間之後資源如果已被修改,則傳回最新的資料”。如果響應的狀态碼是 304 Not Modified ,則表示資源在用戶端指定的時間之後沒有再被修改了。
起内容協商作用的請求頭
主要協商服務端應該傳回的資料類型。
+-------------------+
| Header Field Name |
+-------------------+
| Accept |
| Accept-Charset |
| Accept-Encoding |
| Accept-Language |
+-------------------+
-
Accept
媒體類型,例如 text/plain。
對應響應頭為: Content-Type
-
Accept-Charset
字元集 unicode
-
Accept-Encoding
字元編碼,例如 gzip。
對應響應頭為: Content-Encoding
-
Accept-Language
語言
協商頭的值可以多個,用逗号隔開,表示服務端可以根據情況選擇。每種選項都有一個比重(0 ~ 1),用分号與選項隔開,放在分号之後。可以省略比重,此時會被解釋為 1。
例如:
Accept: text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c
表示更希望擷取 text/html 或者 text/x-c 這兩種媒體類型。如果伺服器不支援這兩種類型,則傳回 text/x-dvi 這種類型。如果也不支援 text/x-dvi,則傳回 text/plain 這種類型。如果都不支援,則傳回 406 Not Acceptable 。
響應狀态碼
1xx 資訊
-
100 Continue
當用戶端的 Expect 頭部包含 100-continue 的時候,服務端傳回該狀态碼表示知道用戶端要發送大量的資料,并且初始資料已被接收,服務端目前不打算拒絕該請求,用戶端可以繼續發送請求。
RFC 7231 對 Expect 的值隻定義了 100-continue 這一種。如果用戶端傳送了其他值,服務端可能傳回 417 Expectation Failed。
-
101 Switching Protocols
用戶端頭部包含 Upgrade 時,服務端傳回該狀态碼表示願意切換協定。
2xx 成功
-
成功建立資源後,在響應頭 Location 中傳回資源的位置。
在實踐中,會碰到一個問題:用戶端并不總是關心該資源的位置,而是關注檢視該資源内容的前端位址。不能将該位址放在響應體,因為 201 要求響應體必須為空。應該把這個連結資訊放到響應頭 Link 裡面。
- 服務端接受用戶端的請求,但請求未處理完。服務端傳回目前處理的狀态,以及指向該處理的狀态監測器。用戶端可使用該監測器擷取執行狀态。
-
203 Non-Authoritative Information
由代理傳回。表示請求成功,服務端傳回了 200,但由于響應有效載荷被轉換代理修改,是以傳回該狀态碼。
-
205 Reset Content
讓用戶端将導緻剛剛請求被發送的那部分頁面(例如表單)重置為它的初始狀态。
3xx 重定向
表示使用者代理需要再做其他動作來滿足剛才的請求。比如 Location 字段指定了一個 URI,使用者代理可能自動重定向到該 URI。
重定向有四種類型:
- 資源可能在一個不同的 URI 上可以用。屬于這種類型的狀态碼包括:
- 301 (Moved Permanently)
- 302 (Found)
- 307 (Temporary Redirect)
- 請求的資源有多種表征,用戶端可以選擇最合适的表征。屬于這種類型的狀态碼包括:
- 300 (Multiple Choices)
- 重定向到一個不同的資源,該資源代表了對請求的間接響應。屬于這種類型的狀态碼包括:
- 303 (See Other)
- 重定向到一個已緩存的結果。屬于這種類型的狀态碼包括:
- 304 (Not Modified)
以下是各個狀态碼的補充說明:
-
300 Multiple Choices
請求的資源存在,但是有多種表征。由于用戶端沒有明确表示需要哪種表征,服務端無法替用戶端決定。服務端将這些不同表征的 URI 放在頭部 Link 中。
服務端可在 Location 指定服務端傾向的其中一種表征,供用戶端自動重定向。
-
301 Moved Permanently
目标資源被配置設定了新的 永久 的 URI,後續請求應該使用新的 URI。服務端将新的 URI 放在 Location 中,用戶端可以根據這個字段的值自動重定向。
由于曆史原因,使用者代理一旦收到該狀态碼,後續請求可能将 POST 轉為 GET。如果不能接受這樣的轉換,則應該使用 307 Temporary Redirect。
-
302 Found
目标資源 暫時 存放在不同的 URI,後續請求應該使用原先的 URI。服務端将新的 URI 放在 Location 中,用戶端可以根據這個字段的值自動重定向。
-
服務端讓用戶端重定向到一個不同的資源,該資源的 URI 放在 Location 中,目的是為原始請求提供一個間接的響應。這種重定向可能持續多次,并且使用者代理應該将最終的結果作為原始請求的響應。
例如 POST 建立資源後,可以使用這個狀态碼将用戶端重定向至新資源的位址。
-
304 Not Modified(RFC 7232)
當 GET 或者 HEAD 請求附帶 Last-Modified 或 ETag 時,如果滿足條件,則傳回該狀态碼。表示用戶端資料的版本已是最新,服務端不再傳回這些資料。
響應頭應包含以下頭部的任何一個:Cache-Control, Content-Location, Date, ETag, Expires 和 Vary 。
- 305 Use Proxy(已廢棄)
- 306 Unused(已廢棄)
-
307 Temporary Redirect
使用者代理在自動重定向的時候 禁止改變 請求方法。
- 308 Permanent Redirect(RFC 7238)
需要特别注意的是:
狀态碼 | 暫時/永久 | 可能改變請求方法 | RFC |
---|---|---|---|
301 | 永久 | 是 | 7231 |
302 | 暫時 | ||
307 | 否 | ||
308 | 7238 |
4xx 用戶端錯誤
憑據(credential):登入過的證明。如 Cookie,Token。
- 請求的句法有問題(例如請求的第一行不按照标準來)、欺騙性的請求路由、不合法的請求内容等。當其他 4xx 無法表達錯誤類型的時候,也使用該狀态碼。
-
401 Unauthorized(RFC 7235)
不包含有效的憑據。服務端的響應頭必須包含 WWW-Authenticate,告知具體原因。無效的憑據:空憑據、過期憑據。
-
402 Payment Required
僅作為保留狀态碼,以便未來對此狀态碼做具體定義。
-
403 Forbidden
資源存在,但用戶端沒有權限通路。分為帶有效憑據和無效憑據的情況。但最終都要求用戶端提供一個有效且具有權限的憑據。
-
404 Not Found
服務端目前沒有找到請求的資源。404 并不意味着資源在未來不會出現。如果服務端通過一些資訊知道該資源永遠不會再出現,則應傳回 410 Gone。
未必找不到資源才傳回 404。在實踐中,如果服務端不想暴露 “資源存在” 這一資訊給用戶端,則可以傳回該狀态碼。
-
405 Method Not Allowed
目标資源不支援該請求方法。例如某個資源不支援 DELETE,而用戶端對該資源發起 DELETE 請求。
-
406 Not Acceptable
用戶端請求頭包含 Accept、Accept-Charset、Accept-Encoding、Accept-Language 時,服務端發現資源無法滿足用戶端的要求,且不想傳回一個預設的資源表征。
服務端應該在響應的有效載荷中列出可用的選擇。
-
407 Proxy Authentication Required(RFC 7235)
類似于 401,但 407 用于用戶端和代理之間。用于表示如果要使用代理,必須提供有效憑據。代理的響應頭必須包含 Proxy-Authenticate,告知具體原因。
-
408 Request Timeout
服務端未能在特定時間内接收一個完整的請求,并且要關閉該連接配接。
-
請求與目标資源目前的狀态産生沖突。
常出現在對版本化的資源做 PUT 時,資源已被其他請求變更,目前請求不是基于資源最新版本變更的。服務端可以在響應的有效載荷裡面包含幫助用戶端合并兩個版本的資訊。
這個狀态碼在一些地方被用于 POST 請求的響應,用于表示要建立的資源已存在。
-
410 Gone
與 404 相似,但 410 表示資源很可能永遠都不存在。
-
411 Length Required
用戶端請求頭不包含 Content-Length
-
412 Precondition Failed(RFC 7232)
請求頭中一個或者多個測試條件不滿足。用戶端想要在目标資源處于某種狀态的時候才更新該資源,而如果用戶端所預期的狀态和該資源目前的狀态不一緻,則傳回該狀态碼。
-
413 Payload Too Large
請求體(有效載荷)的大小超過了服務端設定的限制。如果這種限制是臨時的,則服務端響應頭應包含 Retry-After 表示用戶端可以過一段時間再嘗試。
-
414 URI Too Long
URI 太長。可能是由于重定向導緻 POST 轉為 GET,也可能是用戶端惡意攻擊,還可能是用戶端不小心傳了過多的資料。
- 用戶端請求頭 Content-Type 或者 Content-Encoding 指定的值,或者服務端根據請求體的内容來識别,發現其類型不被目标資源所支援。
-
417 Expectation Failed
跟用戶端請求頭 Expect 對應(隻定義了 100-continue 一種)。如果用戶端傳送了服務端不支援的 Expect 類型,則報錯。
-
422 Unprocessable Entity(RFC 4918)
導緻 400 的條件都不滿足的情況下,服務端仍然無法處理該請求。
可以用于業務校驗不通過的場景。
-
426 Upgrade Required
用戶端的請求由于 HTTP 版本過低被服務端拒絕執行,如果用戶端願意更新 HTTP 版本,服務端才會執行。
響應頭必須包含 Upgrade。例如 Upgrade: HTTP/3.0
- 401 和 403 的差別(登入、權限)
- 404 和 410 的差別(是否永久不存在)
- 408 和 504 的差別(服務端接收用戶端逾時、代理接收服務端逾時)
- 409 的場景(資源支援版本)
5xx 服務端錯誤
-
500 Internal Server Error
用戶端請求沒問題,但服務端碰到了錯誤,導緻無法執行完請求。
-
501 Not Implemented
用戶端使用的請求方法服務端沒有實作,即對任意資源都不能使用該請求方法。
-
502 Bad Gateway
網關或者代理伺服器收到了一份來自上遊伺服器的非法響應。
-
503 Service Unavailable
服務端因為暫時性的負載過高或者臨時維護導緻服務無法使用。
如果負載過高,服務端不一定使用該狀态碼,而是直接拒絕連接配接。
-
504 Gateway Timeout
網關或者代理伺服器未能在指定時間内收到上遊伺服器的響應。
-
505 HTTP Version Not Supported
服務端不支援或者拒絕支援用戶端使用的 HTTP 主版本。

本文采用知識共享署名 2.5 中國大陸許可協定進行許可。歡迎轉載,演繹或用于商業目的,但是必須保留本文的署名 schaepher(包含連結)。如您有任何疑問或者授權方面的協商,請給我留言。