前記
http協議是前端經常打交道的協議之一,發展至今已經到了2.0版本,這兩天我刷完了《圖解HTTP》,讓我對與HTTP協議的發展史有了更深層的瞭解
全球資訊網的出現和HTTP的誕生
時間要回到1989年的聖誕節,那一天李爵士發明了世界上第一個網頁瀏覽器WorldWideWeb(同時也是網頁編輯器)和第一個網頁伺服器。為了在網頁瀏覽器和網頁伺服器中傳輸文字資訊,李爵士將超文字嫁接到因特網上(超文字的概念並不是李爵士提出來的),由此誕生了超文字標記語言(HTML)
為了在全球資訊網中釋出和接收HTML,李爵士發明了超文字傳輸協議協議,也就是HTTP的誕生
最初的HTTP/0.9
1991年,李爵士釋出文章標誌著全球資訊網公共專案的開始。在建立HTTP標準規範時,制定者主要想把HTTP當作傳輸HTML文件的協議,所以起初的協議非常簡單。
請求由單行指令構成,以唯一可用方法GET開頭,其後跟目標資源的路徑(一旦連線到伺服器,協議、伺服器、埠號這些都不是必須的)。
GET /mypage.html
響應也極其簡單的:只包含響應文件本身。
<HTML>這是一個非常簡單的HTML頁面</HTML>
跟後來的版本不同,HTTP/0.9的響應內容並不包含HTTP頭,這意味著只有HTML檔案可以傳送,無法傳輸其他型別的檔案;也沒有狀態碼或錯誤程式碼:一旦出現問題,一個特殊的包含問題描述資訊的HTML檔案將被髮回,供人們檢視。
這時的HTTP協議,伺服器傳送完畢後就會關閉TCP連線
升級之後的HTTP/1.0
由於 HTTP/0.9 協議的應用十分有限,瀏覽器和伺服器的迅速發展和擴充套件,使其已經不能夠滿足需要,所以,1996年5月,HTTP協議的1.0版本釋出,這次釋出的內容並沒有被納入標準,而是為1.1版本的構建可擴充套件性的嘗試,更新的內容也非常多,主要有
- 協議版本資訊現在會隨著每個請求傳送(HTTP/1.0被追加到了GET行)
- 狀態碼會在響應開始時傳送,使瀏覽器能瞭解請求執行成功或失敗,並相應調整行為(如更新或使用本地快取)
- 引入了HTTP頭的概念,無論是對於請求還是響應,允許傳輸後設資料,使協議變得非常靈活,更具擴充套件性
- 在新HTTP頭的幫助下,具備了傳輸除純文字HTML檔案以外其他型別文件的能力(感謝Content-Type頭)
此時,HTTP的請求已經變成這樣了
GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
複製程式碼
響應變成了這樣
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
<html>
<body>Hello World</body>
</html>
複製程式碼
此時的HTTP協議已經初具雛形,和我們現在看到的非常像,這是第一個在通訊中指定版本號的HTTP協議版本,至今仍被廣泛採用,但是它並不是沒有問題的,它仍然存在著0.9版本的問題,就是TCP連線不可以複用,每次傳送請求都需要建立TCP連線,新建成本高,還需要傳送前的預熱。所以HTTP/1.0效能較差,為了解決這個問題,有些瀏覽器在傳送請求時,使用了一個非標準的Connection
欄位。
Connection: keep-alive
複製程式碼
伺服器不關閉TCP連線,以便其他請求複用,同樣回覆
Connection: keep-alive
複製程式碼
一個可以複用的TCP連線就建立了,直到客戶端或伺服器主動關閉連線。但是,這不是標準欄位,不同實現的行為可能不一致,因此不是根本的解決辦法。
標準的誕生HTTP/1.1
就在HTTP/1.0釋出的幾個月後,HTTP/1.1就誕生了,這次版本它進一步完善了HTTP協議,哪怕到今天都是最流行的協議之一
HTTP/1.1 消除了大量歧義內容並引入了多項改進:
- 連線可以複用,節省了多次開啟TCP連線載入網頁文件資源的時間。
- 增加流水線操作,允許在第一個應答被完全傳送之前就傳送第二個請求,以降低通訊延遲。
- 支援響應分塊。
- 引入額外的快取控制機制。
- 引入內容協商機制,包括語言,編碼,型別等,並允許客戶端和伺服器之間約定以最合適的內容進行交換。
- 感謝
Host
頭,能夠使不同域名配置在同一個IP地址的伺服器上。
已經發展到這個時候,那麼協議完美了嗎
事實上並沒有,雖然可以複用TCP連線,並且可以在一個連線中同時傳送多個HTTP請求,但是服務端的處理是按順序的,這就造成一個請求阻塞了,那麼後面的所有請求的響應都會阻塞,這稱為"隊頭堵塞"(Head-of-line blocking)
解決方法一是減少請求數,二是同時多開持久連線。但一般瀏覽器最多同時建立六個TCP連線
消除HTTP瓶頸的SPDY
隨著時代的發展,web的用途開始變得多種多樣,比如線上購物網站、社交網路服務、企業或組織內部的各種管理工具,等等
雖然這些功能已經通過web應用和指令碼程式實現,但在效能上未必最優,這是因為HTTP協議上的限制以及自身效能有限。
以下這些HTTP標準就會成為瓶頸
- 一條連線上服務端只可以返回一個請求
- 請求只能從客戶端開始,客戶端不可以接收除響應以外的指令
- 請求/響應首部未經壓縮就傳送。首部資訊越多延遲越大
- 傳送冗長的首部。每次互相傳送相同的首部造成的浪費較多
- 可任意選擇資料壓縮格式。非強制壓縮傳送
HTTP的功能不足可以通過建立一套全新的協議來彌補,可是目前基於HTTP協議的web瀏覽器已經遍佈全球,因此無法完全拋棄HTTP,有一些新協議的規則是基於HTTP的,並在此基礎上新增了新的功能
Google在2010年釋出了SPDY,其開發目標旨在解決HTTP的效能瓶頸,縮短Web頁面的載入時間(50%)
SPDY沒有完全改寫HTTP協議,而是在應用層和傳輸層之間通過新加會話層的形式運作。同時,考慮到安全性問題,SPDY規定通訊中使用SSL。
SPDY還是採用HTTP建立通訊連線。因此還是可以使用HTTP的GET或POST等方法、Cookie以及HTTP報文等。
HTTP獲得了以下額外的功能
- 多路複用流
- 賦予請求優先順序
- 壓縮HTTP首部
- 推送功能
- 伺服器提示功能
SPDY解決了部分問題,但是並沒有從根本解決問題。
但這個協議在Chrome瀏覽器上證明可行以後,就被當作 HTTP/2 的基礎,主要特性都在 HTTP/2 之中得到繼承。
期盼的HTTP/2.0的誕生
HTTP/2.0的目標是改善使用者在使用Web時的速度體驗
對比HTTP/1.1,改善有如下幾點
- HTTP/2是二進位制協議而不是文字協議。它不能再手動讀取和建立,改善的優化技術現在可被實施。
- 這是一個複用協議。並行的請求能在同一個連結中處理,移除了HTTP/1.x中順序和阻塞的約束。
- 頭部壓縮,因為headers在一系列請求中常常是相似的,其移除了重複和傳輸重複資料的成本。
- 其允許伺服器在客戶端快取中填充資料,通過一個叫伺服器推送的機制來提前請求。