/

HTTP 協議

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 與 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
2
GET /a-page HTTP/1.1
Host: flaviocopes.com

怎樣才能測試這個呢?使用telnet。這是一個命令行工具,可以讓我們連接到任何服務器並向其發送命令。

打開你的終端,然後輸入 telnet flaviocopes.com 80

這將打開一個終端,終端上會顯示:

1
2
3
Trying 178.128.202.129...
Connected to flaviocopes.com.
Escape character is '^]'.

您現在已經連接到了托管我的博客的 Netlify Web 服務器上。現在,您可以輸入:

1
2
3
GET /axios/ HTTP/1.1
Host: flaviocopes.com

然後按下空行上的回車鍵來發送請求。

響應如下:

1
2
3
4
5
6
7
8
9
10
11
HTTP/1.1 301 Moved Permanently
Cache-Control: public, max-age=0, must-revalidate
Content-Length: 46
Content-Type: text/plain
Date: Sun, 29 Jul 2018 14:07:07 GMT
Location: https://flaviocopes.com/axios/
Age: 0
Connection: keep-alive
Server: Netlify

Redirecting to https://flaviocopes.com/axios/

如您所見,這是我們從服務器獲得的 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
HTTP/1.1 200 OK
Cache-Control: public, max-age=0, must-revalidate
Content-Type: text/html; charset=UTF-8
Date: Sun, 29 Jul 2018 14:20:45 GMT
Etag: "de3153d6eacef2299964de09db154b32-ssl"
Strict-Transport-Security: max-age=31536000
Age: 152
Content-Length: 9797
Connection: keep-alive
Server: Netlify

<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>HTTP requests using Axios</title>
....

我截斷了響應,但您可以看到返回的是網頁的 HTML 內容。

其他資源

HTTP 服務器不僅僅傳輸 HTML 文件,通常還會傳輸其他文件:CSS、JS、SVG、PNG、JPG 等許多不同類型的文件,這取決於配置。

HTTP 完全可以傳輸這些文件,並且客戶端將了解文件類型,因此可以以正確的方式解釋它們。

這就是 Web 的工作原理:當瀏覽器檢索到 HTML 頁面時,它會解釋並通過對相同服務器的其他 HTTP 請求檢索以正確顯示所需的資源(CSS、JavaScript、圖像等)。