淺顯易懂的前端知識點(二)——HTTP協議基礎

HTTP 協議的初印象:javascript

是基於 TCP/IP 協議的應用層協議,不涉及數據包的傳輸,主要規定了客戶端和服務器之間的通訊格式,默認使用 80 端口。css

1 HTTP 協議 0.9 版(1991 年)

是個弱智協議,客戶端發起請求之後,服務器只能返回 HTML 格式的字符串,不能迴應別的格式。html

只有一個 GET 命令:java

GET /index.html
複製代碼

上面命令表示,TCP 鏈接(connection)創建後,客戶端向服務器請求(request)網頁 index.html。瀏覽器

服務器發送完畢,就關閉 TCP 鏈接。緩存

2 HTTP 協議 1.0 版(1996 年)

與 0.9 版本相比,有如下幾點變化:bash

  • 這個版本容許發送的內容變多了,不只能夠傳輸文字,還能傳輸圖像、視頻、二進制文件。
  • 除了 GET,POST、HEAD 這兩個命令均可以用,瀏覽器和服務器的互動手段增長了。
  • HTTP 請求和迴應的格式也變了。每次通訊都必須包括頭信息,用來描述一些元數據。

新增的功能還有:服務器

  • 狀態碼
  • 多字符集支持
  • 多部分發送
  • 權限
  • 緩存
  • 內容編碼
2.1 請求形式:
<!-- 請求命令, 必須在尾部添加協議版本(HTTP/1.0)-->
GET /HTTP/1.0
<!-- 多行頭信息,描述了客戶端的狀況 -->
User-Agent: Mozilla/5.0(Macintosh: Intel Mac PS X 10_10_5)
<!-- 客戶端表示本身能夠接受任何格式的數據 -->
Accept:*/*
複製代碼
2.2 迴應格式
<!-- 頭信息 -->
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires:Thu, 05 Dec 1997 16:00:00 GMT
Server: Apache 0.84

<!-- 數據 -->
<html>
  <body>Hello World</body>
</html>
複製代碼

其中,頭信息的第一行是 「協議的版本 + 狀態碼(status code) + 狀態描述」app

2.3 Content-Type 字段

Content-Type 字段的做用是告訴客戶端從服務端返回的數據是什麼格式。ide

常見的 ContentType:

  • 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

數據類型的構成包括一級類型和二級類型,中間用斜槓隔開。這些類型都被稱爲 MIME type。

MIME type 不只用於 HTTP 請求,也能夠用於別的地方,好比 HTML 網頁。

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- 等同於 -->
<meta charset="utf-8" /> 
複製代碼
2.4 數據壓縮

客戶端在請求的時候,用 Accept - Encoding 字段說明本身能夠接受哪些壓縮方法。

Accept-Encoding: gzip, deflate
複製代碼

而服務器使用 Content-Encoding 字段說明數據的壓縮方法。

Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
複製代碼
2.5 HTTP/1.0 協議的缺點

每一個 TCP 鏈接只能發送一個請求,數據發送完畢鏈接就關閉了,若是要請求別的資源,必須再新建一個鏈接。

可是 TCP 鏈接的成本很高,由於客戶端和服務器的三次握手,而且啓動發送的速率較慢。

有一些瀏覽器爲了解決 TCP 會關閉的問題,採用了非標準的 Connection 字段。

瀏覽器請求和服務器迴應都帶有這個字段:

Connection: keep-alive
複製代碼

這樣的話,一個能夠複用的鏈接創建了,直到客戶端或者服務器主動關閉鏈接。可是不一樣的瀏覽器實現不一樣,這不是一個好的解決辦法。

3 HTTP 協議 1.1 版(1997 年)

3.1 持久鏈接

相比 1.0 版,1.1 版最大的變化是保持鏈接,即默認 TCP 鏈接不關閉,能夠被多個請求複用,不用再聲明 Connection: keep-alive。

那怎麼關閉呢?若是客戶端或者服務器發現對方一段時間內沒有活動,就能夠主動關閉鏈接。不過最好仍是客戶端在發送最後一個請求的時候,發送一個 Connection:close,明確要求服務器關閉 TCP 鏈接。

另外,對於同一個域名,大多數瀏覽器容許同時創建 6 個持久鏈接。

3.2 管道機制

管道機制: 在同一個 TCP 鏈接裏,客戶端能夠同時發送多個請求。

之前的作法是客戶端先發送 A 請求,而後再發送 B 請求。管道機制是容許瀏覽器同時發送 A 請求和 B 請求,可是服務器仍是按照順序進行的,先回應 A 請求再回應 B 請求。

3.3 區分數據包

一個 TCP 鏈接如今能夠傳送多個迴應,勢必就要有一種機制,區分數據包是屬於哪個迴應的。

Content-length 字段的做用,聲明本次迴應的數據長度。

Content-Length: 3495
複製代碼

上面的字段告訴客戶端,本次迴應的長度是 3495 個字節,後面的字節就屬於下一個迴應了。

因此,使用 Content-Length 字段的前提條件是,服務器發送迴應以前,必須知道迴應的數據長度。

而在 1.0 版本中,這個字段能夠存在,也能夠不存在,由於服務端關閉了 TCP 鏈接說明數據包已經全了。

3.4 其餘功能

1.1 版新增了不少動詞方法:PUT、PATCH、HEAD、OPTIONS、DELETE。

客戶端的請求頭信息增長了 Host 字段,用來指定服務器的域名。

這個字段能夠將請求發往同一臺服務器的不一樣網站。

如:

Host: www.example.com
複製代碼
3.5 缺點

"隊頭堵塞": 在 1.1 版協議中,雖然能夠在一個 TCP 中發送多個請求,服務器只有處理完一個迴應,纔會進行下一個迴應。要是前面的迴應特別慢,後面就會有許多請求排隊等着。

爲了不這個問題,只有兩種方法:一是減小請求數,二是同時多開持久鏈接。

因此產生了不少網頁優化技巧,好比合並腳本和樣式表,將圖片嵌入 CSS 代碼,域名分片等,可是 HTTP 協議設計得更好的話,這些工做徹底沒有必要作的。

4 SPDY 協議 (2009 年)

2009 年,谷歌公開了本身搞的 SPDY 協議,主要爲了解決 HTTP/1.1 效率不高的問題。

這個協議最終被看成了 HTTP/2 的基礎。

5 HTTP 協議 2 版

HTTP/2 協議不叫 HTTP/2.0,這是由於標準委員會不在打算髮布子版本,下一個新的版本將會是 HTTP/3。

5.1 二進制協議

HTTP 協議的頭確定是文本(ASCII 碼),數據體能夠是文本,也能夠是二進制。

但 HTTP/2 協議頭和數據體都是二進制,是一個不折不扣的二進制協議。

這裏的頭和數據體都換了一個身份叫作 「幀」:頭信息幀和數據幀。

二進制協議的好處就是能夠定義額外的幀,HTTP/2 有近十種幀,爲未來的高級應用打好了基礎,由於二進制解析比文本解析更方便。

5.2 多工

HTTP/2 協議複用 TCP 鏈接,也就是說客戶端和服務端能夠同時發送或者回應多個請求。

好比說,在一個 TCP 裏,客戶端給服務端發送了 A 和 B 兩個請求,按道理說應該先處理 A 請求,可是服務端發現 A 請求有點費勁兒,就先把 A 請求中處理好的發出去,接着迴應 B 請求,完事兒之後再發送 A 請求中剩下的部分。

像這樣雙向,實時的通訊,就叫作多工(Multiplexing)。

5.3 數據流

HTTP/2 的數據包不是按照順序發送的,同一個鏈接裏的數據包可能屬於多個請求。因此須要一個編號,這個編號指明數據包屬於哪個請求或者回應。

這裏有一個概念叫作數據流,咱們把一個請求或者回應的全部數據包合在一塊兒稱爲一個數據流。每一個數據流都有一個獨一無二的編號,數據包發送的時候都必須標定數據流編號。

客戶端請求的數據流編號一概爲基數,而服務端迴應的數據流編號爲偶數。

在 HTTP/1.1 中終止請求的方式只能是關閉 TCP 鏈接,而如今能夠發送一個信號:(RST_STREAM 幀),取消這個數據流。

也就是說 HTTP/2 能夠取消某一次請求,同時能保證 TCP 鏈接打開,能夠被其餘請求所使用。

此外,客戶端能夠指定數據流的優先級,優先級高的服務器越早響應。

5.4 頭信息壓縮

由於協議不帶有狀態,每次請求都必須附上全部信息。有一些信息是重複的,這樣會影響數據傳輸速度,浪費帶寬。

HTTP/2 採用頭信息壓縮機制能夠減小不利影響。首先是將信息壓縮後再發送(gzip 或者 compress),其次是客戶端 和服務器同時維護一張頭信息表,這個表很神奇的地方在於能夠利用索引進行管理,只要咱們發送索引就能夠表示咱們傳輸的信息,這樣就可以提升速度。

5.5 主動推送

HTTP/2 容許服務器在沒有通過容許的狀況下,能夠主動向客戶端推送資源 。這個過程叫作服務器推送(server push)。

舉一個例子,別發送郵件給咱們的時候,郵箱會冒個彈框出來告訴咱們有人往郵箱裏投遞了一封郵件。注意,此時咱們並無刷新網頁。

服務器推送還可能用到消息提醒,靜態資源自動推送到服務端等場景。

相關文章
相關標籤/搜索