HTTP-HTTPS-HTTP2-HTTP3-QUIC-WebSocket 協議詳解

名詞解釋

URI 結構如下,URL 是 URI 中 Web Resource 的子集,例如 http/ftp 協議。

HTTP

HTTP 全稱 Hypertext Transfer Protocol 超文本傳輸協議,主要基於 TCP 實現的應用層協議,特點有:

版本變化:

TCP 握手流程:

三次握手原因。爲了避免因傳輸異常導致包時序問題,一端在發消息時必須要接收到對方的回包確認。例如客戶端因網絡延遲發了兩個 SYN,如果沒有第三次握手 ACK,則服務端會二次建立連接。


四次揮手原因。一端發送 FIN 是表示自己不發數據,但是還可以接收另一端發送的數據。所以要結束 TCP 連接,需要雙方都 FIN+ACK 兩次 RTT。根據 wiki 也有可以通過三次揮手結束連接,但是需要同時關閉雙端。
結束 TIME_WAIT 需要等待 2MSL(最大報文段生存時間) 才能到 CLOSED 狀態。一是避免最後的 ACK 丟白需要重發,二是要確保此次連接的數據包在網絡中消失,避免跟下次連接混淆。

請求與響應包:

響應狀態碼分爲 1xx 臨時響應、2xx 成功、3xx 重定向、4xx 請求錯誤、5xx 服務器錯誤。常見狀態碼見附錄。

WebSocket

WebSocket 是基於 TCP 的全雙工通信協議。背景是 web app 網絡通信是基於 HTTP 協議,每次服務端跟客戶端通信都需要建立一次 HTTP 連接,WebSocket 在應用層重新設計,提供機制可以讓 web 網絡通信在一個 TCP 連接中實現多次數據傳輸。
WebSocket 與 HTTP 的聯繫
爲了兼容 HTTP 服務,WebSocket 握手協議是在 HTTP 基礎上進行擴展。但是 WebSocket 其他部分與 HTTP 無關,完全是在 TCP 之上封裝的應用與 web 的協議,其中包括以下內容:
o 爲瀏覽器添加基於 Web Origin 標準的安全模型
o 添加了一種尋址和協議命名機制,以支持一個端口上的多種服務和一個 IP 地址上的多個主機名
o 在 TCP 之上分層成幀機制,以回到建立 TCP 的 IP 數據包機制,但沒有長度限制
o 在代理和其他中間人的情況下額外設計一套關閉握手協議

WebSocket URI 格式:
ws-URI = "ws:" "//" host [":" port] path [ "?" query ]
wss-URI = "wss:" "//" host [":" port] path [ "?" query ]

WebSocket 握手頭部:

RFC: https://tools.ietf.org/html/rfc6455

HTTPS

HTTPS 全稱 Hypertext Transfer Protocol Secure,是在 HTTP 協議中添加 TLS/SSL 擴展,支持加密數據傳輸。
爲了確保數據在傳輸過程中不被讀取 (加密算法)、篡改 (數字簽名)、調包 (數字證書),以下對相關術語進行解釋。
加密算法

  1. 對稱加密
    對稱加密算法的特點是算法公開、計算量小、加密速度快、加密效率高。對稱加密有很多種算法,由於它效率很高,所以被廣泛使用在很多加密協議的核心當中。不足之處是,交易雙方都使用同樣鑰匙,安全性得不到保證。常見的對稱加密有 DES、AES 等。
  2. 非對稱加密
    非對稱加密使用一對 “私鑰 - 公鑰”,用私鑰加密的內容只有對應公鑰才能解開,反之亦然。非對稱加密有以下特性:

非對稱加密不需要共享同一份祕鑰,安全性要比對稱加密高,但由於算法強度比對稱加密複雜,加解密的速度比對稱加解密的速度要慢。常見的非對稱加密有 RSA、ESA、ECC 等。

數字簽名
數字簽名就是用摘要算法提取出源文件的摘要並用私鑰進行加密後的內容。摘要一致則說明文件沒有被篡改過,即使摘要被解密也無法還原數據內容。
摘要算法有以下特性:

一般使用摘要算法來校驗原始內容是否被篡改。常見的摘要算法有 MD5、SHA 等。

數字證書
數字證書是一個經證書授權中心數字簽名的包含公開密鑰擁有者信息以及公開密鑰的文件,用於認證密匙的有效性。一般會包含公鑰、公鑰擁有者名稱、CA 的數字簽名、有效期、授權中心名稱、證書序列號等信息。

數字證書如何確保列出的用戶就是公鑰的擁有者呢?關鍵點是 CA 的數字簽名,CA 會用自己的私鑰將證書內容的摘要進行加密。因爲 CA 的公鑰是公開的,任何人都可以用公鑰解密出 CA 的數字簽名的摘要,再用同樣的摘要算法提取出證書的摘要和解密 CA 數字簽名後的摘要比對,一致則說明這個證書沒有被篡改過,可以信任。

參考:https://www.jianshu.com/p/ffe8c203a471

TLS 握手過程:
TLS 握手協議分爲基礎握手協議 (Basic TLS handshake) 與雙向認證協議(Client-authenticated TLS handshake)。雙向認證協議是在 Basic 基礎上增加了客戶端發送證書的步驟。

  1. 客戶端發送「ClientHello」,內容包括:支持的協議版本,比如 TLS1.0 版,一個客戶端生成的隨機數 Random1(稍後用於生成 “會話密鑰”),支持的加密算法(如 RSA 公鑰加密)和支持的壓縮算法。
  2. 服務端發送「ServerHello」,內容包括:客戶端與服務端支持的最高協議版本,一個服務器生成的隨機數 Random2,CipherSuite 與壓縮算法(如 RSA)。如果是複用 session,還會帶上 session ID。
  3. 服務端發送「ServerCertificate」證書。服務器會將自己的證書下發給客戶端,其中 Certificates 即是證書(除了網站的 CA 證書外,還一併把該 CA 證書的中級證書下發,所以是一個證書鏈),證書內包含公鑰。
  4. (雙向認證) 服務端發送 CertificateRequest。請求客戶端證書。
  5. 服務端發送「ServerHelloDone」。完成協商。
  6. (雙向認證) 客戶端發送 Certificate。包含客戶端證書以及公鑰。
  7. 客戶端發送「ClientKeyExchange」。生成隨機數 Random3,用證書的公鑰加密生成 PreMasterSecret。服務端用私鑰解密 PreMasterSecret 得到 Random3。
  8. (雙向認證) 客戶端發送 CertificateVerify。用客戶端證書私鑰根據上一個消息生成簽名,服務端用客戶端公鑰解密,確認客戶端證書有效。
  9. 雙端根據 Random1、Random2、Random3 用協商的加密算法生成密鑰
  10. 客戶端發送「ChangeCipherSpec」。表示之後數據均以加密方式傳輸。
  11. 客戶端發送「Finished」。發送加密的 Finished 消息,內容是基於前一次消息生成的 hash 以及 Message Authentication Code (MAC)。服務端驗證 Finished 消息是否有效,無效則關閉連接。
  12. 服務端發送「ChangeCipherSpec」以及「Finished」。同上。
  13. 開始加密數據傳輸。

基礎流程:

公私鑰交換流程:

TLS 1.3 改進
冷啓動握手從 2-RTT 到 1-RTT。

  1. 客戶端將預測的協議版本和 key share 發給服務端。
  2. 服務端選擇協議並返回 key share 跟證書 (用 key share 加密) 以及 Finished。
  3. 客戶端用 key share 驗證證書獲取公鑰,發送 Finished。

Resumption 熱啓動
tls 1.2 熱啓動實現方式是發送 ClientHello 時帶上 session ID(缺點是需要每個連接服務器保存 session 狀態) 或者 session Ticket(序列化的 session),服務端確認後直接返回 Finished,然後雙端複用 Pre-master secret,這樣只需要 1-RTT 即可完成握手。但是存在風險是如果 Pre-master secret 被破解,則 session 數據就會泄露。
tls 1.3 改進了熱啓動方式,達到 0-RTT。具體實現是在初次握手後通過加密通道傳輸 Pre-Shared Key(用於確認使用者身份,而不是密鑰),客戶端熱啓動時同時傳加密數據以及 Pre-Shared Key,服務端如果驗證 Pre-Shared Key 有效則直接解密數據。

tls 1.3 冷熱啓動握手圖見 spec,搜索 figure 即可。
https://tools.ietf.org/html/rfc8446#section-4.2.11

常見攻擊
Downgrade attack。man-in-the-middle 攻擊的一種,篡改客戶端請求向服務端協商舊版本的加密方式,然後通過已知的舊版本漏洞破解加密請求。通常服務端去掉向後兼容性就可以解決問題,但是會犧牲部分可用性。另外 tls 1.3 標準定義在雙端 Finished 消息中校驗之前所有握手消息的 MAC,如果存在篡改則關閉連接。
Replay attack。攻擊者 sniff 並錄製正常客戶端請求,然後向服務端請求同樣的內容,從而欺騙服務端獲取敏感數據。例如 0-RTT 的首次數據場景,因爲服務端無法驗證數據來源,所以最好的方式是首次請求避免敏感信息、狀態改變等。

HTTP/2

相比 HTTP1.x,2.0 在以下方面做了改進:
Streams, messages, and frames
HTTP2 在應用層引入 Binary framing 機制將傳輸數據從單一請求 - 響應包細分成更小的部分進行數據傳輸,從而可以更靈活地控制數據,引入多路複用、優先級、數據流控制等傳輸策略。
Binary framing 引入 Stream、message 和 frame 概念。一個 TCP 連接傳輸多個 bidirectional streams(包含 stream id 跟 priority);stream 由多個 messages 構成,message 是 HTTP 消息例如一次 request 或 response,包含一個或多個 frames;frame 包含不同類型的數據,是數據傳輸最小單位,例如 header,body 爲不同的 frame,可以通過 stream id 進行組裝。

multiplexing 單 TCP 連接多路複用
一次 TCP 連接在 HTTP1 只能一次請求響應,HTTP2 將多次請求響應劃分爲 frames,交替 (interleave) 傳輸,最終在對端根據 stream id 進行組裝。

Stream prioritization
客戶端給每個 stream 分配 1-256 優先級附在 header frame 中,再根據 stream 依賴樹請求服務器。RFC 沒有規定服務端的行爲,不同的服務提供商可能實現不同的處理策略,例如 cloudflare 根據客戶端優先級將 stream 劃分爲多個池,每個池分配一定的帶寬傳輸數據。

cloudflare solution:https://blog.cloudflare.com/better-http-2-prioritization-for-a-faster-web/
RFC:https://tools.ietf.org/html/rfc7540#page-24

HTTP headers 壓縮
基本思路是對標準 header 鍵值用固定字典編碼,自定義鍵值用動態字典編碼,無法用字典情況下用 Huffman 編碼。固定字典是基於 RFC 標準定義的固定鍵值字符串排列;動態字典是在一次 connection 過程中動態更新自定義鍵值字符串;Huffman 編碼是用於第一次傳輸自定義鍵值,雙端解碼後在動態字典中更新,第二次傳輸即可用字典方式編碼,Huffman 表是 RFC 基於大量現實 header 統計的概率表。對自定義頭部用預定義字典或動態字典 (隨一次 connection 更新) 編碼。

例子:https://blog.cloudflare.com/hpack-the-silent-killer-feature-of-http-2/
ref:https://tools.ietf.org/html/rfc7541

HTTP/2 Server Push
用於服務端控制資源下發。服務端基於客戶端已有的 connection,發送 PUSH_PROMISE header frame 帶上資源 url 以及預留的 stream id 給客戶端,然後傳輸 data frame 將資源下發給客戶端,期間客戶端也可以控制 Push 參數。與一般客戶端請求響應不一樣的是,Push 需要遵守 same-origin policy 以及服務端必須是 authoritative。

RFC: https://tools.ietf.org/html/rfc7540#page-60

HTTP3

HTTP3 是將傳輸層的 TCP 替換爲基於 UDP 的 QUIC 協議,應用層對齊實現 HTTP1/2 的語法,從而解決 TCP 建立連接慢、隊頭擁塞等問題。目前 HTTP3 與 QUIC 標準處於 Internet-Draft 狀態,還要經過 Proposed Standard、Internet Standard 兩個階段才能正式成爲標準。客戶端 Chrome 和 Firefox 僅在主線版本支持,另外也有三方庫支持服務端 / 客戶端 HTTP3,具體見 wiki 資料。

wiki: https://en.wikipedia.org/wiki/HTTP/3

QUIC

QUIC 最初被提案時是 "Quick UDP Internet Connections" 的縮寫,是基於 UDP 的多路複用和安全的通用傳輸層協議。目前客戶端有 Chrome、Firefox、Opera、Curl 支持,服務端有 LiteSpeed、Nginx、Cloudflare 支持,截至 2019 年 8 月,有 3.2% 的網站使用 QUIC。區別於 IETF(Internet Engineering Task Force) 的標準 QUIC,Google QUIC(gQUIC) 本意是設計爲通用協議在 Chromium 中支持 HTTP(S),同時也在跟進支持最新的 QUIC 標準。QUIC 具有以下特性:
o Stream multiplexing
o Stream and connection-level flow control
o Low-latency connection establishment
o Connection migration and resilience to NAT rebinding
o Authenticated and encrypted header and payload

QUIC 協議內容:
Connection
與服務端的連接。包括握手流程定義,傳輸協議、加密協議協商。connection ID 用於定義 endpoints 之間的 QUIC 路由,即使某一端 ip 或端口改變了,也可以將數據傳輸中的 connection 遷移到新的地址,而不需要重新傳輸已送達的數據。類似 IP 報頭的 source/destination address,QUIC 數據包 Packet 的 header 也包含 Source Connection ID(非必須) 和 Destination Connection ID,這兩個 ID 在雙端定義了 Packet 歸屬於哪個 connection,用於重組數據。ID 在 QUIC 握手時初始化,連接過程中可能被改變。

Stream
用於傳輸有序字節流數據。分爲單向 unidirectional 和雙向 bidirectional stream。可以在流程控制 (flow control) 和限制 (stream limits) 條件下同時創建任意多個 stream 傳輸任意大小的數據,但是不能保證不同 stream 中傳輸字節的順序。發送數據是通過 STREAM frames 帶上 stream ID、Offset fields 以及 data,對端再根據 ID 和 Offset 進行重組。

Packet and Frame

關於 Packet:

握手流程
下圖是 1-RTT 握手流程,每行格式是 "{packet_type}[{packet_num}]: {frame_type}[{frame_payload}] {frame_type1}[{frame_payload1}] ..."

  1. 客戶端發送 Initial 包。包含客戶端 Source Connection ID(從 0 開始遞增) 以及 TLS 握手幀 CRYPTO Frame(Client Hello bytes)。
  2. 服務端發送 UDP 包。UDP 中包括三類 Packet。Initial 包,包含 CRYPTO Frame(Server Hello bytes) 以及 ACK(請求的 packet_num);QUIC 握手幀 HandShake 包,包含 CRYPTO Frame(證書);1-RTT encrypted 包,包含數據幀 STREAM Frame(Stream ID, 幀 Offset, 數據長度以及字節數據)。
  3. 客戶端發送 UDP 包。UDP 中包括三類 Packet。Initial 包,包含 ACK;HandShake 包,包含結束的 CRYPTO Frame 以及 ACK;1-RTT encrypted 包,包含返回數據幀 STREAM Frame 以及 ACK。
  4. 服務端發送 UDP 包。UDP 中包括兩類 Packet。數據包 1-RTT encrypted 以及握手包 HandShake。

下圖是 QUIC 0-RTT 握手流程。與 TLS Resumption 熱啓動優化思路類似。具體流程見 RFC。

流量控制 (Flow Control)
流量控制是對接收方的數據緩衝大小限制,從而避免快速發送方碾壓慢速接收方及惡意發送者大量消耗接收方內存的情況。同樣,爲了限制連接內的併發,QUIC 終端控制其對端可以發起的最大累計 stream。具體有以下幾項:

連接遷移 (Connection Migration)
當連接一方的地址發生改變,將舊連接遷移到新的地址上,避免重傳已接收的數據。
必要條件:
因爲 QUIC 在握手過程中地址必須不變,所以需要在握手完成之後才能發起連接遷移。
除了服務端使用 Preferred Address 情況下,遷移只能由客戶端發起。
遷移步驟:

  1. 探測地址是否可達。客戶端發送 PATH_CHALLENGE 幀 (包含自定義 Data),服務端響應 PATH_RESPONSE(包含請求的自定義 Data)。如果發生超時,則地址不可達。同時爲了確保服務端有可用的 connection ID,客戶端可以發送 NEW_CONNECTION_ID 幀創建新的 connection。
    2.(可選) 初始化新的 connection。重置擁塞控制 congestion controller 以及擁塞通知 ECN capability。
  2. 發起遷移。客戶端用新地址發送 non-probing 幀 (除了 PATH_CHALLENGE, PATH_RESPONSE, NEW_CONNECTION_ID, PADDING 以外的幀類型),服務端回包並且驗證客戶端地址,即可完成連接遷移。

常見網絡攻擊以及防禦方案
Handshake Denial of Service
攻擊方法:其目的在於使目標電腦的網路或系統資源耗盡,使服務暫時中斷或停止,導致其正常用戶無法訪問。例如針對 TCP 常見的 SYN flood attack,不斷髮送 SYN 包要求服務器建立連接,導致所有端口被異常佔用。
QUIC 防禦方案:加密握手完成後,所有包都是加密並且身份驗證過,不符合的包會被丟棄。

Amplification Attack
攻擊方法:思路是攻擊者僞造目標 IP 向第三方發起請求,第三方返回更多數據給目標導致資源耗盡。針對 QUIC 攻擊的具體實現是攻擊者首先連接第三方獲得 address validation token,然後用此 token 以及目標 IP 發起 0-RTT 請求,僞造目標 IP 熱啓動,第三方驗證熱啓動 token 合法,則發送 0-RTT 響應給目標 IP。
防禦方案:限制 address validation tokens 的使用和生命週期,例如短時間內不接收多個相同 token。

Optimistic ACK Attack
攻擊方法:增加 ACK 參數中收到數據長度,欺騙服務端傳輸比實際帶寬要多得多的數據。
防禦方案:QUIC 在發送 Packet 時會累加 packet numbers,所以服務端通過刻意跳過某些 packet numbers 刻意檢測出客戶端是否惡意發包。

Slowloris Attacks
Stream Commitment Attack
攻擊方法:客戶端創建儘可能多的 connection 或者 stream,持續發送少量心跳數據,導致服務端資源被佔用。
防禦方案:通過接入層防禦,部署 QUIC 時限制每個 IP 的連接數、限制長連接等。

Stream Fragmentation and Reassembly Attacks
攻擊方法:發送方故意只發送 stream 部分數據,導致接收方需要創建整個 stream 大小的 buffer 或數據結構。或者接收方故意不發送 ACK 包,導致發送方一直持有並重傳發送數據。
防禦方案:根據可用內存限制 flow control 的 window 大小,防止內存佔用超過資源。

Stateless Reset Oracle
攻擊方法:思路是攻擊者僞造 RESET 包使服務端正常連接被重置,類似的攻擊有 TCP reset injection,最常見的例子是訪問 google 出現 "The connection was reset"。QUIC 的 RESET 包的 stateless reset token 是由 static key 以及 connection ID 計算得出,攻擊者將正常 Packet 轉發到其他共享 static key 並且沒有 connection 的 endpoint,則服務端會誤以爲 connection 不存在繼而發送 RESET 包並且重置連接。
防禦方案:服務端管理共享 static key 的 endpoint,確保 Packet 能發送到有 connection 的 endpoint。

Version Downgrade
攻擊方法:通過版本協商使用低版本不安全的 QUIC。
防禦方案:QUIC 標準暫無多版本的協商行爲。

QUIC RFC: https://tools.ietf.org/html/draft-ietf-quic-transport-24
QUIC with TLS RFC: https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#name-introduction
中文 QUIC RFC: http://docs.wxclimb.top/draft-ietf-quic-transport-zh.html#fc-credit

Challenges remaining for QUIC

網絡基礎設施已經基於 TCP 存在廣泛的優化,但是對 UDP 是限速甚至是禁止。Google 在早期實驗中就存在少量連接被拒絕的問題。

Does QUIC make the world faster ?

對於網絡耗時,論文 [1] 對比了 HTTP2 跟 QUIC+SPDY,在不同網絡環境下測試網頁加載時間 / 資源請求耗時。結論是:

  1. QUIC 在少量小資源 / 大資源 / 弱網情況下佔優:QUIC is faster (1.2-4.5X) when pages consist of few small-sized objects. QUIC also performs better when the page consists of large-sized objects. QUIC can achieve faster page loads in poor network conditions of lower bandwidth, high delay and lossy network.
  2. QUIC 在大量小資源情況下不如 HTTP2:However, Page load with QUIC is slower (1.1-3.2X) when page consists of many small-sized objects. One possible reason for this is that the QUIC toy server is not optimized to be used efficiently with Chromium browser.

2019 年論文 [2] 對 TCP 做業界通用的優化,對齊 QUIC 傳輸層參數,測試不同網絡環境下頁面加載 / 顯示時間。結論是 QUIC 均優於 TCP(HTTP2),弱網環境下優勢更明顯。
還有資料 [3] 從實際應用角度提出對 QUIC 質疑。例如端對端加密限制網絡鏈路的優化,CPU 以及內存佔用高,擁塞控制 (congestion control) 可能搶佔其他類型的連接帶寬等。

[1]P. Biswal, O. Gnawali, "Does QUIC make the Web faster?", Proc. IEEE GLOBECOM, pp. 1-6, Dec. 2016. http://www2.cs.uh.edu/~gnawali/papers/quic-globecom2016.pdf
[2]"A Performance Perspective on Web Optimized Protocol Stacks: TCP+TLS+HTTP/2 vs. QUIC" arXiv:1906.07415v1 [cs.NI] 18 Jun 2019. https://arxiv.org/pdf/1906.07415.pdf
[3]"QUIC and HTTP/3 : Too big to fail?!" https://calendar.perfplanet.com/2018/quic-and-http-3-too-big-to-fail/
https://en.wikipedia.org/wiki/QUIC#cite_note-QUIC_Design_Doc-3
https://blog.cloudflare.com/the-road-to-quic/
https://yucianga.info/?p=819

附錄

常用請求碼:
1xx(臨時響應)
表示臨時響應並需要請求者繼續執行操作的狀態代碼。

代碼 說明
100 Continue(繼續) 請求者應當繼續提出請求。 服務器返回此代碼表示已收到請求的第一部分,正在等待其餘部分。
101 Switching Protocols(切換協議) 請求者已要求服務器切換協議,服務器已確認並準備切換。

2xx (成功)
表示成功處理了請求的狀態代碼。

代碼 說明
200 OK(成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。
201 Created(已創建) 請求成功並且服務器創建了新的資源。
202 Accepted(已接受) 服務器已接受請求,但尚未處理。
203 Non-Authoritative Information(非授權信息) 服務器已成功處理了請求,但返回的信息可能來自另一來源。
204 No Content(無內容) 服務器成功處理了請求,但沒有返回任何內容。
205 Reset Content(重置內容) 服務器成功處理了請求,但沒有返回任何內容。
206 Partial Content(部分內容) 服務器成功處理了部分 GET 請求。

3xx (重定向)
表示要完成請求,需要進一步操作。 通常,這些狀態代碼用來重定向。

代碼 說明
300 Multiple Choices(多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。
301 Moved Permanently(永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。
302 Found(臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。
303 See Other(查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。
304 Not Modified(未修改) 自從上次請求後,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。
305 Use Proxy(使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。
307 Temporary Redirect(臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

4xx(請求錯誤)
這些狀態代碼表示請求可能出錯,妨礙了服務器的處理。

代碼 說明
400 Bad Request(錯誤請求) 服務器不理解請求的語法。
401 Unauthorized(未授權) 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。
403 Forbidden(禁止) 服務器拒絕請求。
404 Not Found(未找到) 服務器找不到請求的網頁。
405 Method Not Allowed(方法禁用) 禁用請求中指定的方法。
406 Not Acceptable(不接受) 無法使用請求的內容特性響應請求的網頁。
407 Proxy Authentication Required(需要代理授權) 此狀態代碼與 401(未授權)類似,但指定請求者應當授權使用代理。
408 Request Timeout(請求超時) 服務器等候請求時發生超時。
409 Conflict(衝突) 服務器在完成請求時發生衝突。 服務器必須在響應中包含有關衝突的信息。
410 Gone(已刪除) 如果請求的資源已永久刪除,服務器就會返回此響應。
411 Length Required(需要有效長度) 服務器不接受不含有效內容長度標頭字段的請求。
412 Precondition Failed(未滿足前提條件) 服務器未滿足請求者在請求中設置的其中一個前提條件。
413 Request Entity Too Large(請求實體過大) 服務器無法處理請求,因爲請求實體過大,超出服務器的處理能力。
414 Request-URI Too Long(請求的 URI 過長) 請求的 URI(通常爲網址)過長,服務器無法處理。
415 Unsupported Media Type(不支持的媒體類型) 請求的格式不受請求頁面的支持。
416 Requested Range Not Satisfiable(請求範圍不符合要求) 如果頁面無法提供請求的範圍,則服務器會返回此狀態代碼。
417 Expectation Failed(未滿足期望值) 服務器未滿足 "期望" 請求標頭字段的要求。

5xx(服務器錯誤)
這些狀態代碼表示服務器在嘗試處理請求時發生內部錯誤。 這些錯誤可能是服務器本身的錯誤,而不是請求出錯。

代碼 說明
500 Internal Server Error(服務器內部錯誤) 服務器遇到錯誤,無法完成請求。
501 Not Implemented(尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。
502 Bad Gateway(錯誤網關) 服務器作爲網關或代理,從上游服務器收到無效響應。
503 Service Unavailable(服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。
504 Gateway Timeout(網關超時) 服務器作爲網關或代理,但是沒有及時從上游服務器收到請求。
505 HTTP Version Not Supported(HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://segmentfault.com/a/1190000021390130