HTTP/0.9 到 HTTP/3 進化史

一個HTTP請求流程

在地址欄輸入網址後:html

  1. 構建請求:瀏覽器構建請求行信息如GET /index.html HTTP1.1,準備發起網絡請求
  2. 查找緩存:發起網絡請求前,瀏覽器先在緩存中查詢是否有要請求的文件,若有,則攔截請求,返回資源副本,並結束請求,如無則繼續
  3. 準備IP地址和端口:查找DNS緩存,如無則進行DNS查詢,最終拿到請求域名對應的IP地址,HTTP協議端口默認8080
  4. 等待TCP隊列:瀏覽器中同一個域名最多隻能創建6個TCP鏈接,多出來的須要排隊等待
  5. 創建TCP鏈接:瀏覽器經過TCP三次握手與服務器創建鏈接
  6. 發送HTTP請求
  7. 服務器處理HTTP請求並響應
  8. 斷開TCP鏈接:四次揮手

HTTP/0.9

1991年提出,最初的目的只是爲了傳輸體積很小的HTML文件,所以稱爲超文本傳輸協議。特色:瀏覽器

  1. 只有一個請求行如GET /index.html,沒有請求頭和請求體
  2. 服務器沒有返回頭信息,僅僅返回數據
  3. 返回文件由於都是HTML格式,因此以ASCII字符流來傳輸

HTTP/1.0

1994年出現了撥號上網,同年網景推出了瀏覽器,萬維網進入了高速發展的階段。爲支持多種類型的文件下載HTTP/1.0引入了請求頭和響應頭。引入了狀態碼、提供了Cache機制來緩存下載過的資源、加入了用戶代理字段。緩存

例如HTTP請求頭告訴服務器本身但願服務器返回的文件類型、壓縮方法、文件的編碼方式、語種:安全

accept: text/html
accept-encoding: gzip, deflate, br
accept-Charset: ISO-8859-1,utf-8
accept-language: zh-CN,zh
複製代碼

服務器返回本身最終選擇的方式,如壓縮方法、文件類型:bash

content-encoding: br
content-type: text/html; charset=UTF-8
複製代碼

HTTP/1.1

持久鏈接

HTTP/1.0中每一對請求響應都須要單獨的TCP鏈接,HTTP/1.1增長了持久鏈接,在一個TCP鏈接上進行屢次請求和響應。服務器

默認是Connection: keep-alive,即開啓,設置Connection: close手動關閉。markdown

配合Keep-Alive: timeout=5, max=1000來設定鏈接時長。其中timeout指定一個空閒鏈接須要保持打開狀態而最小時長(單位:秒)。max指定這次鏈接的最大請求數。cookie

目前瀏覽器對於同一域名容許最多同時創建6個TCP持久鏈接。網絡

不成熟的管線化

管線化指將多個HTTP請求批量提交給服務器,服務器依然根據請求順序來回復瀏覽器的請求。因爲種種緣由,這個技術的嘗試失敗了。併發

支持虛擬主機

HTTP/1.0中一個IP地址只能綁定一個域名,所以服務器只能支持一個域名。隨着虛擬主機技術的發展,須要實現一臺物理主機上綁定多個各自擁有域名的虛擬主機。HTTP/1.1在請求頭中增長了Host字段,用來表示當前域名,供服務器區分。

支持動態生成的內容

HTTP/1.0中須要在響應頭中設置完整的數據大小如Content-Length: 901,以便瀏覽器根據數據大小準確接收數據。但對於動態生成的內容,傳輸前不知道最終大小,致使瀏覽器沒法正確接收全部數據。

HTTP/1.1引入了Chunk transfer機制,服務器將數據分割成若干大小的數據塊,每一個數據塊發送時都會附上數據塊的長度,最後使用一個零長度的塊來結束。這樣就能夠支持動態內容了。

客戶端Cookie、安全機制
客戶端Cookie機制

用戶登陸時,服務器驗證用戶登陸信息正確後,會生成一段表示用戶身份的字符串,並寫入響應頭Set-Cookie字段裏,而後發送給瀏覽器,如Set-Cookie: UID=3431uad;

瀏覽器將Set-Cookie字段中的值保存到本地,當用戶再次訪問服務器時,瀏覽器會讀取以前保存的Cookie數據並寫入請求頭的Cookie字段中,如Cookie: UID=3431uad;

服務器根據Cookie字段中的值查找該用戶的信息,判斷是否已登陸,而後生成包含該用戶信息的頁面數據,返回給瀏覽器。

安全機制

HttpOnly:Set-Cookie: id=a3fWa; HttpOnly。禁止JavaScript經過document.cookie訪問cookie,以阻止XSS攻擊。

SameSite: Set-Cookie: id=a3fWa; SameSite=Strict。SameSite有三個值:

  • Node: 瀏覽器會在同站請求、跨站請求下繼續發送cookies,不區分大小寫。
  • Strict:瀏覽器只在訪問相同站點時發送cookie。
  • Lax:新版瀏覽器的默認選項,在跨站點的狀況下,只容許從第三方站點經過連接打開或get請求攜帶Cookie,經過post或img、iframe等標籤加載的url不會攜帶cookie。
問題

TCP通道中,須要等待前面的請求返回後才能進行下一次請求,若是某個請求由於某些緣由沒有及時返回,就會阻塞後面的全部請求,這就是隊頭阻塞的問題。

HTTP/2

多路複用

2015年5月正式發佈HTTP/2協議規範,該協議使用多路複用機制,實現一個域名只使用一個TCP長鏈接,並消除了隊頭阻塞問題。多路複用技術能充分利用帶寬,最大限度規避了TCP慢啓動所帶來的問題,使得頁面資源的傳輸速度獲得了大幅提高。 使用HTTP/2能帶來20% ~ 60%的效率提高。

HTTP/2添加了一個二進制分幀層,將通過的請求轉換爲一個個帶有請求ID編號的幀,服務器接收到全部幀以後,將全部相同ID的幀合併爲一條完整的請求信息,處理完請求後,將響應也一樣用二進制分幀層轉換爲一個個帶有請求ID編號的幀,瀏覽器接收到響應幀後根據ID編號將數據提交給對應的請求。

瀏覽器能夠隨時發送請求,而沒必要等待前一個請求接收到響應以後;一樣,服務器也能夠按需決定優先返回哪些內容,而沒必要在乎順序,由於每份數據都有ID來標識。這樣就實現了資源的並行傳輸。

HTTP/2的其餘特性:
  1. 能夠設置請求的優先級:服務器不須要按順序處理請求,所以對於一些優先級比較高的請求,如關鍵資源的加載,能夠在發送請求時標註優先級,服務器接收到請求後,會優先處理優先級高的請求。
  2. 服務器推送:服務器能夠將數據提早推送到瀏覽器,例如:用戶請求首頁HTML文件後,服務器知道該頁面會引用幾個重要的JavaScript文件和CSS文件,因而能夠附帶將這些文件一併發送給瀏覽器,加快渲染速度。
  3. 頭部壓縮:HTTP/2對請求頭和響應頭進行了壓縮,在一些大量發送請求體比較少的請求的狀況下,傳輸效率會獲得很大的提高。

HTTP/3

HTTP/2解決了應用層面的隊頭阻塞問題,但只要仍是基於TCP,就避免不了TCP的隊頭阻塞問題。而TCP在設計之初就是爲了單連接而設計。

TCP的問題
  1. 隊頭阻塞:TCP傳輸的數據被拆分紅一個個按順序排列的數據包,接收端收到後再按順序將這些數據包組成原始數據。若是在傳輸過程當中,有一個數據包由於網絡故障或其它緣由丟失,以後的數據就得等待丟失的數據包被從新傳輸過來,形成了阻塞。而HTTP/2只有一個鏈接,其餘全部請求都會被阻塞。隨着丟包率的增長,HTTP/2的傳輸效率也愈來愈差。
  2. 創建鏈接的延時:TCP創建鏈接時的三次握手,若是是HTTPS還有TLS鏈接握手,總體就須要3~4個RTT(TCP1.5個,TLS根據1.2/1.3版本會有不一樣的表現)。
  3. 協議僵化:互聯網須要不少中間設備來說多個網絡互聯,這些中間設備包括路由器、防火牆、NAT、交換機等。它們一般依賴一些不多升級的軟件,這些軟件使用了大量TCP特性,即使客戶端升級了TCP協議,新協議的數據通過這些中間設備時,也可能會由於不被理解而丟棄。此外,TCP協議都是經過操做系統內核來實現的,一般操做系統的更新都滯後於軟件的更新,也是致使TCP協議僵化的一個緣由。
QUIC協議

HTTP/3基於UDP協議實現了相似於TCP的多路複用數據流、傳輸可靠性等功能,這套功能被稱爲QUIC協議。

  1. 流量控制、傳輸可靠性功能:QUIC在UDP的基礎上增長了一層來保證數據傳輸可靠性,它提供了數據包重傳、擁塞控制、以及其餘一些TCP中的特性。
  2. 集成TLS加密功能:目前QUIC使用TLS1.3,減小了握手所花費的RTT數。
  3. 多路複用:同一物理鏈接上能夠有多個獨立的邏輯數據流,實現了數據流的單獨傳輸,解決了TCP的隊頭阻塞問題。

  1. 快速握手:因爲基於UDP,能夠實現使用0 ~ 1個RTT來創建鏈接。
HTTP/3的挑戰
  1. 目前服務器和瀏覽器端都沒有對HTTP/3提供比較完整的支持。
  2. 部署問題,系統內核對UDP的優化遠達不到TCP的優化程度。
  3. 中間設備僵化問題,這些設備對UDP的優化程度遠低於TCP,據統計使用QUIC協議時,大約有3% ~ 7%的丟包率。
相關文章
相關標籤/搜索