HTTP協議概述

落日樓臺H 發表於 2020-12-04

HTTP歷史

起源

蒂姆·伯納斯·李(Tim Berners-Lee)爵士(1955年出生於英國)是全球資訊網的發明者,網際網路之父。

1989 年,歐洲核子研究組織(CERN)的蒂姆·博納斯-李(Tim Berners-Lee)博士提出一個構想:藉助多文件之間相互關聯形成的超文字(HyperText),連成可參閱的 WWW(World Wide Web,全球資訊網),以幫助遠隔兩地的研究者們共享知識。在這個構想中,他提出了 3 項 WWW 構建的關鍵技術:HTML, URI, HTTP.

網際網路之父:蒂姆·伯納斯·李(Tim Berners-Lee)、溫頓·瑟夫(Vint Cerf 原名:Vinton Gray “Vint” Cerf )、羅伯特·卡恩(Robert Elliot Kahn)等。

v2_3d104486596041fa8f76865e83a1fde6_img_000
@Tim Berners-Lee


HTTP 0.9

1989年 Tim Berners-Lee 蒂姆·伯納斯-李在其論文中確立了:

1. URI:統一資源識別符號
2. HTML:超文字標記語言
3. HTTP:超文字傳輸協議

這個版本的 HTTP 只允許 Get 方法。

HTTP 1.0

1996年正式釋出

  1. 增加 HEAD、POST 等新方法;
  2. 增加響應狀態碼(status code),標記可能的錯誤原因;
  3. 引入了協議版本號概念;
  4. 引入了 HTTP Header 的概念,讓 HTTP 處理請求和響應更加靈活;
  5. 傳輸的資料不再限於文字;

此時的 HTTP/1.0 還只是一份參考文件,不是正式標準

HTTP 1.1

1999年 HTTP/1.1 釋出 RFC 文件 2616,後面拆分成了 RFC7230

  1. 增加了PUT、DELETE、OPTIONS 等新的方法;
  2. 增加了快取管理和控制;
  3. 明確了連線保持(keep-alive),允許持續連線;
  4. 允許響應資料分塊(chunked),利於傳輸大檔案;
  5. 強制要求 Host 頭,讓網際網路主機託管成為可能;

HTTP/1.1 優缺點

  1. HTTP 最大的優點是簡單、靈活和易於擴充套件;

  2. HTTP 擁有成熟的軟硬體環境,應用的非常廣泛,是網際網路的基礎設施;

  3. HTTP 是無狀態的,可以輕鬆實現叢集化,擴充套件效能,但有時也需要用 Cookie 技術來實現“有狀態”;

  4. HTTP 是明文傳輸,資料完全肉眼可見,能夠方便地研究分析,但也容易被竊聽;

  5. HTTP 是不安全的,無法驗證通訊雙方的身份,也不能判斷報文是否被竄改;

  6. HTTP 的效能不算差,但不完全適應現在的網際網路,還有很大的提升空間。

HTTP 2

2015年 RFC-7540,起初叫做 SPDY 協議

  1. 二進位制協議,不再是純文字;
  2. 可發起多個請求,廢棄了 1.1 裡的管道;
  3. 使用專用演算法壓縮頭部,減少資料傳輸量;
  4. 允許伺服器主動想客戶端推送資料;
  5. 增強了安全性,事實上要求加密通訊。

HTTP 2.0 通過頭壓縮、分幀、二進位制編碼、多路複用等技術提升效能;
面臨的問題:主要市場還是在1.1的時代,普及率比較低。
使用 TCP 存在的問題:建立連線耗時(1.5RTT); 進行TLS連線耗時(1-2RTT); TCP的隊頭阻塞並沒有徹底解決(丟包重傳)

HTTP 3

目前還沒正式釋出,是有 Google 發起的心協議,叫做 QUIC 協議,在2018年,網際網路標準化組織 IETF 將 HTTP over QUIC 改名為 HTTP 3.
QUIC 協議通過基於 UDP 自定義的類似 TCP 的連線、重試、多路複用、流量控制技術,進一步提升效能。

從古至今實時資料傳輸(音訊、視訊、遊戲等)都面臨卡頓、延遲等問題,而 QUIC 基於 UDP 的架構和改進的重傳等特性,能夠有效的提升使用者體驗。
目前 B站 也已經接入 QUIC。

HTTPS

HTTPS 協議(HyperText Transfer Protocol over Secure Socket Layer):一般理解為 HTTP+SSL/TLS,通過 SSL 證照來驗證伺服器的身份,併為瀏覽器和伺服器之間的通訊進行加密。

由網景公司(Netscape)在1994年首次提出,隨後擴充套件到網際網路上。
在2000年代末至2010年代初,HTTPS開始廣泛使用,以確保各型別的網頁真實,保護賬戶和保持使用者通訊,身份和網路瀏覽的私密性。

那麼SSL又是什麼?

SSL(Secure Socket Layer,安全套接字層):1994年為 Netscape 所研發,SSL 協議位於 TCP/IP 協議與各種應用層協議之間,為資料通訊提供安全支援。

TLS(Transport Layer Security,傳輸層安全):其前身是 SSL,它最初的幾個版本(SSL 1.0、SSL 2.0、SSL 3.0)由網景公司開發,1999年從 3.1 開始被 IETF 標準化並改名,發展至今已經有 TLS 1.0、TLS 1.1、TLS 1.2 三個版本。

SSL3.0和TLS1.0由於存在安全漏洞,已經很少被使用到。TLS 1.3 改動會比較大,目前還在草案階段,目前使用最廣泛的是TLS 1.1、TLS 1.2。

SSL發展史(網際網路加密通訊)

  1. 1994年NetSpace公司設計SSL協議(Secure Sockets Layout)1.0版本,但未釋出。
  2. 1995年NetSpace釋出SSL/2.0版本,很快發現有嚴重漏洞
  3. 1996年釋出SSL/3.0版本,得到大規模應用
  4. 1999年,釋出了SSL升級版TLS/1.0版本,目前應用最廣泛的版本
  5. 2006年和2008年,釋出了TLS/1.1版本和TLS/1.2版本

HTTP 是什麼?

在 HTTP/1.1 最新標準 RFC7230 中,是這麼定義 HTTP 的:

The Hypertext Transfer Protocol (HTTP) is a stateless application-level request/response protocol that uses extensible semantics and self-descriptive message payloads for flexible integration with network-based hypertext information systems.

HTTP 協議是一種無狀態的、處於應用層的、以請求/應答方式執行的協議,使用可擴充套件的語義和自描述的資訊格式,與基於網路的超文字資訊系統靈活的相互作用。

關鍵詞:無狀態、引用層、請求/應答、可擴充套件的語義、自描述、超文字

網路分層到底是什麼?

OSI 概念模型

OSI(Open System Interconnection Reference Model),開放式系統互聯通訊參考模型,也就是我們常說的 7 層模型。從它的名稱就可以看出來,OSI 只是一個供參考的概念模型,它從未被真正的實現。

786279743fc8a92a9f9e19310350f7bd

TCP/IP 模型

OSI 只是一個概念模型,而平常工作我們最常用的還是 TCP/IP 模型。TCP/IP 模型其實就是 OSI 模型的簡化版本,也就是我們平時所說的 4 層模型。

ae5f9d5f4d15cb209d3260b8848f80ef
@ TCP/IP 四層模型

其實 TCP/IP 模型與 OSI 模型十分相似,主要是省略了表示層、會話層與物理層的實現。
下面是一張 OSI 模型與 TCP/IP 模型的層級對照圖,大家可以通過對照圖來總結 TCP/IP 模型中各層的職責。

8b78d97dbadaf2cbf5243b48ebec8332
@ OSI 七層模型與 TCP/IP 四層模型對比圖


Http報文

請求報文

GET / HTTP/1.1
Host: 127.0.0.1:9090
Connection: keep-alive
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

1d50925993cb03cb5388f7a9ad2582e2
@ HTTP 請求報文

響應報文

HTTP/1.1 200 ok
Connection: keep-alive
Content-Length: 164
Content-Type: text/html
Date: Sat, 06 Jun 2020 01:53:57 GMT

<html>
...

9c1043faba50c472f173e376e83be475
@ HTTP 響應報文

HTTP 協議的無狀態與持久連線

通常,為了儲存狀態,伺服器傳送的響應報文中會有一個 Set-Cookie 的首部欄位,客戶端獲取到該報文後,就可以儲存 Cookie。下一次請求時,客戶端會將儲存的 Cookie 攜帶在請求報文中傳送給伺服器,伺服器拿到 Cookie 後進行比對,就可以知道是從哪個客戶端發來的請求了。

37903d2dc04fb6843eb789205d43eac3
@ 攜帶 Cookie 的 HTTP 傳輸過程


常見HTTP頭

HTTP的實體資料-內容協商

“多用途網際網路郵件擴充套件”(Multipurpose Internet Mail Extensions),簡稱為 MIME。

Accept <=> Content-Type

Accept 是客戶端可接受的 MIME type,對應的是響應報文裡 Content-Type。

Content-type:

  1. text:文字格式的可讀資料,text/html、text/plain、text/css
  2. image:影像檔案,image/gif、image/jpeg、image/png
  3. audio/video:音訊和視訊資料,audio/mpeg、video/mp4
  4. application:資料格式不固定,必須由上層應用程式來解釋。application/json、application/javascript、application/pdf;application/octet-stream即不透明的二進位制資料。

Accept-Encoding <=> Content-Encoding

Accept-Encoding: 該欄位標記的是客戶端支援的壓縮格式

Content-Encoding:

  1. gzip:GNU zip 壓縮格式,也是網際網路上最流行的壓縮格式;
  2. deflate:zlib(deflate)壓縮格式,流行程度僅次於 gzip;
  3. br:一種專門為 HTTP 優化的新壓縮演算法(Brotli)。

Accept-Language <=> Content-Language

對應客戶端支援的語言和響應的語言型別:

type-subtype:en-US 美式英語、en-GB 英式英語、zh-CN 漢語

b2118315a977969ddfcc7ab9d26cb358

1. 資料型別表示實體資料的內容是什麼,使用的是 MIME type,相關的頭欄位是 Accept 和 Content-Type;
2. 資料編碼表示實體資料的壓縮方式,相關的頭欄位是 Accept-Encoding 和 Content-Encoding;
3. 語言型別表示實體資料的自然語言,相關的頭欄位是 Accept-Language 和 Content-Language;
4. 字符集表示實體資料的編碼方式,相關的頭欄位是 Accept-Charset 和 Content-Type;
5. 客戶端需要在請求頭裡使用 Accept 等頭欄位與伺服器進行“內容協商”,要求伺服器返回最合適的資料;
6. Accept 等頭欄位可以用“,”順序列出多個可能的選項,還可以用“;q=”引數來精確指定權重。

Range <=> Acceot-Range

bytes & Content-Range: bytes 0-31/96

Transfer-Encoding: chunked 分塊傳輸的編碼規則:

“Transfer-Encoding: chunked”和“Content-Length”這兩個欄位是互斥的,也就是說響應報文裡這兩個欄位不能同時出現,一個響應報文的傳輸要麼是長度已知,要麼是長度未知(chunked)。

Cookie <=> Set-Cookie

Cookie屬性

HTTP/1.1 200
Set-Cookie: key=value, Max-Age=10; Expires=Fri, 08-Jun-22 08:19:00 GMT; Domain=www.example.com; Path=/; HttpOnly; SameSite=Strict;

Expires和Max-Age都能控制Cookie的有效期,但是瀏覽器會優先採用 Max-Age計算有效期;

HttpOnly => 防範XSS(跨站指令碼)攻擊

在 JS 指令碼里可以用 document.cookie 來讀寫 Cookie 資料,這就帶來了安全隱患,有可能會導致“跨站指令碼”(XSS)攻擊竊取資料。

屬性 “HttpOnly” 會告訴瀏覽器,此 Cookie 只能通過瀏覽器 HTTP 協議傳輸,禁止其他方式訪問,瀏覽器的 JS 引擎就會禁用 document.cookie 等一切相關的 API,指令碼攻擊也就無從談起了。

SameSite => 防範XSRF(跨站請求偽造)攻擊

  1. SameSite=Strict:嚴格限制 Cookie 不能隨著跳轉連結跨站傳送
  2. SameSite=Lax:允許 GET/HEAD 等安全方法,但是禁止POST跨站傳送

Cache-Control

快取控制頭

HTTP/1.1 200
Cache-Control: max-age=30, no-store, no-cache, must-revalidate, proxy-revalidate, public
  1. max-age:用於控制HTTP快取,相對於伺服器的響應時間;
  2. public/private:public在代理伺服器和中間節點都能快取,但是private只有在目標客戶端可以快取;
  3. no-store:不允許快取,用於變化非常頻繁的資料,例如秒殺頁面;
  4. no-cache:可以快取,但在使用之前要去伺服器驗證是否過期,是否有最新的版本;
  5. must-revalidate:如果快取不過期就可以繼續使用,但過期了還想使用需要找伺服器驗證;
  6. proxy-revalidate:與must-revalidate類似,但是隻有公共資源可以在代理伺服器快取,僅限public的配置的資源;

條件請求

If-Modified-Since: Mon, 27 Jul 2020 10:53:40 GMT
If-None-Match: W/"5f1eb234-b7e"

條件請求的兩個欄位需要配合 ETag 和 Last-modified 才能起效,在第一次請求的時候,伺服器返回上面兩個欄位;再次請求資源的時候,瀏覽器會帶上這兩個資源,使用 If-modified-since 和 If-none-Match 來驗證資源是否過期。如果伺服器返回 304 則讀取瀏覽器的快取檔案。


參考

[1] 極客時間 - 《趣談網路協議》

[2] 極客時間 - 《透視 HTTP 協議》