HTTP 協議
HTTP(超文本傳輸協議)是 TCP/IP 應用協議之一,它是推動互聯網運作的各種協議套件之一。
讓我修改一下:它不僅僅是一個協議,而且是最成功和最受歡迎的協議。
HTTP 使 World Wide Web 運作,使瀏覽器能夠與托管網頁的遠程服務器進行通信。
HTTP 於 1991 年首次標準化,是因為 Tim Berners-Lee 自 1989 年起在歐洲核子研究中心(CERN)的工作。
當時的目標是讓研究人員可以輕鬆地交換和互相連接他們的論文。這是為了讓科學界更好地工作。
那個時候,Internet 主要應用基本上包括 FTP(文件傳輸協議)、電子郵件和新聞組(如今幾乎被廢棄)。
在 1993 年,第一個圖形化網頁瀏覽器 Mosaic 被發佈,從那時開始事情就一飛沖天。
網頁成為了互聯網的殺手應用。
隨著時間的推移,網頁和其周圍的生態系統發生了巨大變化,但基本原則仍然存在。一個進化的例子是:除了網頁之外,HTTP 現在還支持 REST API,這是一種通過 Internet 以編程方式訪問服務的常見方法。
HTTP 在 1997 年進行了一次小的修訂,推出了 HTTP/1.1,而在 2015 年,它的繼任者HTTP/2也被標準化,目前同時由全球各地的主要 Web 服務器所支持。
HTTP 協議被認為是不安全的,就像其他未在加密連接上提供的協議(如 SMTP、FTP)一樣。這就是為什麼現在大力推動使用 HTTPS(在 TLS 上運行的 HTTP)的原因。
也因此,HTTP/2 和 HTTPS 的構建模塊根植於 HTTP。在本文中,我將介紹 HTTP 的工作原理。
HTML 文件
HTTP 是像 Chrome、Firefox、Edge 和其他許多瀏覽器(也稱為客戶端)與 Web 服務器通信的方式。
超文本傳輸協議的名字源於傳輸的不僅僅是文件(如在 FTP - 文件傳輸協議 中),還有使用 HTML 編寫的超文本,並且由瀏覽器以漂亮的形式和互動鏈接表示。
超連接
在網絡瀏覽器內部,可以使用連接來指向其他文檔。
連接由首部部分和文件部分組成。通過域名或 IP 決定協議和服務器地址的第一部分不僅僅適用於 HTTP。
然後是文檔部分。添加到地址部分的任何內容都表示該文檔的路徑。
例如,此文檔地址為https://flaviocopes.com/http/
:
-
https
是協議。 -
flaviocopes.com
是指向我的服務器的域名。 -
/http/
是相對於服務器根路徑的文檔 URL。
路徑可以是嵌套的:https://flaviocopes.com/page/privacy/
,在這種情況下文檔 URL 是 /page/privacy
。
Web 服務器負責解釋請求並在分析後提供正確的響應。
請求
請求中包含哪些內容?
首先是 URL,我們之前已經看到了。
當我們在瀏覽器地址欄中輸入一個地址並按下回車時,在背後,服務器向正確的 IP 地址發送如下所示的請求:
1 | GET /a-page |
其中 /a-page
是您要請求的 URL。
第二部分是 HTTP 方法(也稱為動詞)。
早期的 HTTP 定義了 3 個方法:
-
GET
-
POST
-
HEAD
而 HTTP/1.1 引入了:
-
PUT
-
DELETE
-
OPTIONS
-
TRACE
我們將在一會兒詳細介紹它們。
組成請求的第三個部分是一組 HTTP 標頭。
標頭是一組 key: value
配對,用於向服務器傳遞特定信息,這些信息是預定義的,因此服務器可以理解我們的意思。
我在HTTP 請求標頭列表中詳細描述了它們。
快速查看一下該列表。除了 Host
外,所有這些標頭都是可選的。
HTTP 方法
GET
這是一個非常常用的方法。當您在瀏覽器地址欄中輸入 URL 或單擊鏈接時,就是使用此方法。
它要求服務器將所請求的資源作為響應發送回去。
HEAD
HEAD 與 GET 類似,但它告訴服務器不要發送響應主體,只發送頭信息。
POST
客戶端使用 POST 方法將數據發送到服務器。它通常用於表單,同時也適用於與 REST API 交互。
PUT
PUT 方法用於在特定 URL 創建資源,引數通過請求體傳遞。主要用於 REST API。
DELETE
DELETE 方法用於請求刪除特定 URL 的資源。主要用於 REST API。
OPTIONS
當服務器收到 OPTIONS 請求時,應該回應列表,列出允許該特定 URL 的 HTTP 方法。
TRACE
將收到的請求返回給客戶端。用於調試或診斷目的。
HTTP 客戶端/服務器通信
HTTP 是 TCP/IP 協議套件中大多數協議一樣是無狀態協議。
服務器不知道客戶端的當前狀態。它們只關心得到請求並完成它們。
在這個上下文中,任何先前的請求都沒有意義。這使得 Web 服務器在處理更少的內容時變得非常快速,同時也為它處理大量並發請求提供了帶寬。
HTTP 也非常精簡,在開銷方面的通信速度非常快。這與 HTTP 出現時最常用的協議相對比:TCP 和 POP/SMTP 這些郵件協議,它們需要大量的握手和確認。
圖形化瀏覽器將所有這些通信抽象化,但為了學習目的,我們在這裡將進行演示。
消息由第一行組成,該行以 HTTP 方法開始,然後包含相對資源路徑和協議版本:
1 | GET /a-page HTTP/1.1 |
接下來,我們需要添加 HTTP 請求標頭。正如上面提到的,有許多標頭,但其中唯一強制的是 Host
:
1 | GET /a-page HTTP/1.1 |
怎樣才能測試這個呢?使用telnet。這是一個命令行工具,可以讓我們連接到任何服務器並向其發送命令。
打開你的終端,然後輸入 telnet flaviocopes.com 80
這將打開一個終端,終端上會顯示:
1 | Trying 178.128.202.129... |
您現在已經連接到了托管我的博客的 Netlify Web 服務器上。現在,您可以輸入:
1 | GET /axios/ HTTP/1.1 |
然後按下空行上的回車鍵來發送請求。
響應如下:
1 | HTTP/1.1 301 Moved Permanently |
如您所見,這是我們從服務器獲得的 HTTP 響應。它是一個 301 Moved Permanently 的請求。詳細了解請查看HTTP 狀態碼列表。
基本上它告訴我們資源已經永久移動到另一個位置。
為什麼?因為我們連接到了默認使用 HTTP 的 80 端口,但我的服務器上設置了自動重定向到 HTTPS。
新位置在 Location
的 HTTP 響應標頭中指定。
還有其他標頭,全部在HTTP 響應標頭列表中有描述。
在請求和響應中,請求頭和請求體之間用一個空行分隔。在此示例中,響應體包含字符串:
1 | Redirecting to https://flaviocopes.com/axios/ |
它是 46 字節長,如 Content-Length
標頭中指定。在打開該頁面時它在瀏覽器中顯示,並自動將您重定向到正確的位置。
在這種情况下,我们使用的是 telnet,這是一個可以用來連接任何服務器的低級工具,因此無法進行任何類型的自動重定向。
讓我們再次執行此過程,現在連接到默認端口 443,這是 HTTPS 協議的默認端口。由於要進行 SSL 握手,我們無法使用 telnet。
為了保持簡單,我們將使用另一個命令行工具 curl
。我們無法直接輸入 HTTP 請求,但我們將看到響應:
1 | curl -i https://flaviocopes.com/axios/ |
我們將得到以下響應:
1 | HTTP/1.1 200 OK |
我截斷了響應,但您可以看到返回的是網頁的 HTML 內容。
其他資源
HTTP 服務器不僅僅傳輸 HTML 文件,通常還會傳輸其他文件:CSS、JS、SVG、PNG、JPG 等許多不同類型的文件,這取決於配置。
HTTP 完全可以傳輸這些文件,並且客戶端將了解文件類型,因此可以以正確的方式解釋它們。
這就是 Web 的工作原理:當瀏覽器檢索到 HTML 頁面時,它會解釋並通過對相同服務器的其他 HTTP 請求檢索以正確顯示所需的資源(CSS、JavaScript、圖像等)。