HTTP 是基於 TCP/IP 協議的應用層協議。主要規定了客戶端和服務器之間的通信格式,默認使用80端口。
HTTP0.9
get /index.html 命令,客戶端向服務器請求網頁index.html
服務端返回 html格式的內容
HTTP1.0
引入了POST
命令和HEAD
命令
1.0版的HTTP請求
GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
第一行是請求命令,必須在尾部添加協議版本(HTTP/1.0
)。後面就是多行頭信息,描述客戶端的情況。
服務器迴應
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>
迴應的格式是"頭信息 + 一個空行(\r\n
) + 數據"。其中,第一行是"協議版本 + 狀態碼(status code) + 狀態描述"。
Content-Type:
服務器迴應的時候,必須告訴客戶端,數據是什麼格式。常見的Content-Type
字段的值
text/plain
text/html
text/css
image/jpeg
image/png
image/svg+xml
audio/mp4
video/mp4
application/javascript
application/pdf
application/zip
application/atom+xml
客戶端請求的時候,可以使用Accept
字段聲明自己可以接受哪些數據格式。上面代碼中,客戶端聲明自己可以接受任何格式的數據。
Content-Encoding:
說明數據的壓縮方法
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
客戶端在請求時,用Accept-Encoding
字段說明自己可以接受哪些壓縮方法。
Accept-Encoding: gzip, deflate
另:TCP連接的新建成本很高,因爲需要客戶端和服務器三次握手,並且開始時發送速率較慢。
HTTP1.1
最流行的版本
引入持久連接:可以被多個請求複用。客戶端和服務器發現對方一段時間沒有活動,就可以主動關閉連接。不過,規範的做法是,客戶端在最後一個請求時,發送Connection: close
,明確要求服務器關閉TCP連接。
目前,對於同一個域名,大多數瀏覽器允許同時建立6個持久連接。
引入了管道機制:在同一個TCP連接裏面,客戶端可以同時發送多個請求。
舉例來說,客戶端需要請求兩個資源。以前的做法是,在同一個TCP連接裏面,先發送A請求,然後等待服務器做出迴應,收到後再發出B請求。管道機制則是允許瀏覽器同時發出A請求和B請求,但是服務器還是按照順序,先回應A請求,完成後再回應B請求。
Content-Length:聲明本次迴應的數據長度
分塊傳輸編碼:只要請求或迴應的頭信息有Transfer-Encoding
字段,就表明迴應將由數量未定的數據塊組成。
Transfer-Encoding: chunked
每個非空的數據塊之前,會有一個16進制的數值,表示這個塊的長度。最後是一個大小爲0的塊,就表示本次迴應的數據發送完了。
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25
This is the data in the first chunk
1C
and this is the second one
3
con
8
sequence
0
其他
1.1版還新增了許多動詞方法:PUT
、PATCH
、HEAD
、 OPTIONS
、DELETE
。
另外,客戶端請求的頭信息新增了Host
字段,用來指定服務器的域名。
Host: www.example.com
HTTP/2
HTTP/2 則是一個徹底的二進制協議,頭信息和數據體都是二進制,並且統稱爲"幀"(frame):頭信息幀和數據幀。
二進制協議:頭信息和數據體都是二進制,並且統稱爲"幀"(frame):頭信息幀和數據幀。
多工:HTTP/2 複用TCP連接,在一個連接裏,客戶端和瀏覽器都可以同時發送多個請求或迴應,而且不用按照順序一一對應,這樣就避免了"隊頭堵塞"。
舉例來說,在一個TCP連接裏面,服務器同時收到了A請求和B請求,於是先回應A請求,結果發現處理過程非常耗時,於是就發送A請求已經處理好的部分, 接着迴應B請求,完成後,再發送A請求剩下的部分。
這樣雙向的、實時的通信,就叫做多工(Multiplexing)。
數據流:HTTP/2 將每個請求或迴應的所有數據包,稱爲一個數據流(stream)。數據流發送到一半的時候,客戶端和服務器都可以發送信號(RST_STREAM
幀),取消這個數據流。1.1版取消數據流的唯一方法,就是關閉TCP連接。這就是說,HTTP/2 可以取消某一次請求,同時保證TCP連接還打開着,可以被其他請求使用。
頭信息壓縮:頭信息使用gzip
或compress
壓縮後再發送;另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以後就不發送同樣字段了,只發送索引號,這樣就提高速度了。
服務器推送:HTTP/2 允許服務器未經請求,主動向客戶端發送資源