HTTP/2

HTTP/2（超文本傳輸協議第2版，最初命名為HTTP 2.0），簡稱為h2（基於TLS/1.2或以上版本的加密連接）或h2c（非加密連接），是HTTP協議的的第二個主要版本，使用於全球資訊網。
HTTP/2是HTTP協議自1999年HTTP 1.1的改進版RFC 2616發佈後的首個更新，主要基於SPDY協定。它由互聯網工程任務組（IETF）的Hypertext Transfer Protocol Bis（httpbis）工作小組進行開發。該組織於2014年12月將HTTP/2標準提議遞交至Internet_Engineering_Steering_Group進行討論，於2015年2月17日被批准。 
HTTP/2標準於2015年5月以RFC 7540正式發表。HTTP/2的標準化工作由Chrome、Opera、Firefox、Internet Explorer 11、Safari、Amazon Silk及Edge等瀏覽器提供支持。 
多數主流瀏覽器已經在2015年底支持了該協議。此外，根據W3Techs的數據，截至2021年10月，全球有46.5%的網站支持了HTTP/2。

**協議的制定**
協議制定伊始，工作組章程關注了下列目標和受關心的問題：- 建立一個協商協議標準，即應用層協議協商（ALPN），以便客戶端能夠從HTTP/1.0、HTTP/1.1、HTTP/2乃至其他非HTTP協議中做出選擇。- 與HTTP/1.1在請求方法、狀態碼乃至URI和絕大多數HTTP頭部字段等方面保持高度兼容性。- 通過以下舉措，減少網絡延遲，提高瀏覽器的頁面加載速度：
** 對HTTP頭字段進行數據壓縮（即HPACK算法）；
** HTTP/2服務端推送（Server Push）；
** 請求管線化；
** 修復HTTP/1.0版本以來未修復的隊頭阻塞問題；
** 對數據傳輸採用多路複用，讓多個請求合併在同一TCP連接內。- 支持現有的HTTP應用場景，包括桌面和移動設備瀏覽器、網絡API、不同規格的網絡服務器和正向代理、反向代理服務器軟件、防火牆和CDN等。
Facebook對各方案進行了評價並最終推薦了SPDY協議。HTTP 2.0的首個草稿於2012年11月發佈，其內容基本和SPDY協議相同。

**協議之間的的比較**

**HTTP/2與HTTP/1.1比較**
HTTP/2相比HTTP/1.1的修改並不會破壞現有程序的工作，但是新的程序可以藉由新特性得到更好的速度。
HTTP/2保留了HTTP/1.1的大部分語義，例如請求方法、狀態碼乃至URI和絕大多數HTTP頭字段一致。而HTTP/2採用了新的方法來編碼、傳輸客戶端和服務器之間的數據。

**HTTP/1.1與SPDY的區別**
SPDY（發音同“speedy”）是一個由Google主導的HTTP替代協議。SPDY一開始主要關注降低延遲，採用了TCP通道，但是使用了不同的協議來達到此目的。其與HTTP/1.1相比，主要的改變有：- 實現無需先入先出的多路複用- 為簡化客戶端和服務器開發的消息—幀機制- 強制性壓縮（包括HTTP頭部）- 優先級排序- 雙向通訊

**HTTP/2與SPDY的比較**
HTTP/2的開發基於SPDY進行躍進式改進。在諸多修改中，最顯著的改進在於，HTTP/2使用了一份經過定製的壓縮算法，基於霍夫曼編碼，以此替代了SPDY的動態流壓縮算法，以避免對協議的Oracle攻擊——這一類攻擊以CRIME為代表。此外，HTTP/2禁用了諸多加密套件，以保證基於TLS的連接的前向安全。

**新特性**
在HTTP/2的第一版草案（對SPDY協議的復刻）中，新增的性能改進不僅包括HTTP/1.1中已有的多路複用，修復隊頭阻塞問題，允許設置設定請求優先級，還包含了一個頭部壓縮算法（HPACK）。此外， HTTP/2採用了二進制而非明文來打包、傳輸客戶端和服務器之間的數據。

**幀、消息、流和TCP連接**
有別於HTTP/1.1在連接中的明文請求，HTTP/2與SPDY一樣，將一個TCP連接分為若干個流（Stream），每個流中可以傳輸若干消息（Message），每個消息由若干最小的二進制幀（Frame）組成。這也是HTTP/1.1與HTTP/2最大的區別所在。HTTP/2中，每個用戶的操作行為被分配了一個流編號（Stream ID），這意味著用戶與服務端之間建立了一個TCP通道；協議將每個請求分割為二進制的控制幀與數據幀部分，以便解析。這個舉措在SPDY中的實踐表明，相比HTTP/1.1，新頁面加載可以加快11.81%到47.7%

**HPACK 算法**
HPACK算法是新引入HTTP/2的一個算法，用於對HTTP頭部做壓縮。其原理在於：- 客戶端與服務端根據RFC 7541的附錄A，維護一份共同的靜態字典（Static Table），其中包含了常見頭部名及常見頭部名稱與值的組合的代碼；- 客戶端和服務端根據先入先出的原則，維護一份可動態添加內容的共同動態字典（Dynamic Table）；- 客戶端和服務端根據RFC 7541的附錄B，支持基於該靜態哈夫曼碼錶的哈夫曼編碼（Huffman Coding）。

**服務器推送**
網站為了使請求數減少，通常採用對頁面上的圖片、腳本進行極簡化處理。但是，這一舉措十分不方便，也不高效，依然需要諸多HTTP鏈接來加載頁面和頁面資源。
HTTP/2引入了服務器推送，即服務端向客戶端發送比客戶端請求更多的數據。這允許服務器直接提供瀏覽器渲染頁面所需資源，而無須瀏覽器在收到、解析頁面後再提起一輪請求，節約了加載時間。

**瀏覽器支援**
截至2015年末，主要的瀏覽器的最新版本已經支持HTTP/2這一協議。其中：
*Google Chrome、Mozilla Firefox、Microsoft Edge和Opera已支持HTTP/2，並默認啟用。
*Internet Explorer自IE 11開始支持HTTP/2，並預設啟用。

**h2c的支持度**
HTTP/2的設計本身允許非加密的HTTP協議，也允許使用TLS 1.2或更新版本協議進行加密。協議本身未要求必須使用加密， 惟多數客戶端（例如Firefox、Chrome、Safari、Opera、IE和Edge等）的開發者聲明，他們只會實現通過TLS加密的HTTP/2協議，這使得經TLS加密的HTTP/2成為了事實上的強制標準，而h2c事實上被主流瀏覽器廢棄。

**SPDY退出歷史舞臺**
2015年9月，Google宣佈了移除對SPDY支持的計劃，擁抱HTTP/2，並將在Chrome 51中生效。

**HTTP/2的實現**
HTTP/2工作組在其官方Github上羅列了諸多已經支持該協議的代碼實現。

**批評與爭議**
HTTP/2的開發過程乃至協議本身都曾受到批評。

**針對協議開發本身**
FreeBSD和Varnish cache的開發者Poul-Henning Kamp批評稱，這個標準文件的準備過程短得不切實際，而且未基於除了SPDY之外的任何協議，以至於其他協議失去了對草案進行改進的機會。Kampala批評說，這個協議本身與HTTP不一致，而且還毫無必要地變得極為複雜。他還認為，這個協議違背了互聯網協議的分層原則，例如說，將本屬於TCP傳輸層的流控制（flow control）功能放入了協議中。

**針對加密的爭議**
一開始，以HTTP工作組某位主席為首的成員在郵件列表建議引入強制使用TLS協議實現的HTTP/2（Mandatory TLS in HTTP/2.0），這招致了爭議。批評者認為，加密增加了十分不必要的開銷，而且很多HTTP服務實際上無需加密，提供者也無意為此花費更多的資源。而支持者認為，實踐中TLS加密的開銷微不足道。
Poul-Henning Kamp批評IETF在制定HTTP/2時，遵循了一個特定的“政治議程”（political agenda），壓縮了討論的空間。
強制加密議程的批評者認為，其基於現有的證書框架，對於開源社區並非新創造，亦不是獨特的。2013年，一位思科員工表示，現有證書模型與路由器一類的小型化設備並不兼容，因為現有的證書框架需要為每張證書付出不可避免的成本，還需要進行每年更新的流程。工作組最終未能在強制加密這一點上達成一致，但是大部分客戶端只實現了基於TLS的HTTP/2，使之成為事實標準。
HTTP/2也被批評未能支持機會性加密，即類似SMTP中存在已久的STARTTLS一樣能抵禦被動監控的措施。 批評者指出，HTTP/2的提議違背了IETF自身制定的《最佳實踐 188》（BCP 188） 即 RFC 7258。這份文件指出，被動監控應被當作一種攻擊，IETF指定的標準應當設置抵禦這種攻擊的措施（例如機會性加密）。目前，已經有一系列機會性加密規範被提出
，工作組也制定了draft-ietf-httpbis-http2-encryption-01這一官方版方案。

**參考資料**

**參見**
 超文本傳輸協議（HTTP）- SPDY(已計劃隨NPN一起淘汰)- 多路複用- QUIC- WebSocket

**外部鏈接**
 http://tools.ietf.org/wg/httpbis/ date=20130703110938  工作組主頁- https://http2.github.io/ date=20170426214957  HTTP/2 協議官網- RFC 7540 – 超文本傳輸協議版本 2 (HTTP/2)- RFC 7541 – HPACK: 為 HTTP/2 制定的頭部壓縮算法- //tools.ietf.org/html/draft-mbelshe-httpbis-spdy-00 SPDY Protocol (draft-mbelshe-httpbis-spdy-00)- //tools.ietf.org/html/draft-montenegro-httpbis-speed-mobility-01 HTTP Speed+Mobility (draft-montenegro-httpbis-speed-mobility-01)- //tools.ietf.org/html/draft-tarreau-httpbis-network-friendly-00 Proposal for a Network-Friendly HTTP Upgrade (draft-tarreau-httpbis-network-friendly-00)