每個 Developer 都要知道的 Http Protocol

2023-03-14

作為開發人員,你可能已經聽過 HTTP 協議,它是支撐網絡傳輸的核心協議之一。HTTP 是一個標準的客戶端/伺服器協議,用於在網絡上傳輸資料,也是現代應用程式和網站開發中的關鍵部分。本文將探討 HTTP 協議的基礎知識,以及為什麼每個開發人員都應該了解 HTTP 協議。

logo

說明

情境對話

嗨,小N,你有聽過 HTTP Protocol 嗎?

有點印象,好像是網路傳輸協議的一種?

對的,HTTP 是一種用來在網路上傳輸資料的協議,全名叫做 Hypertext Transfer Protocol。簡單來說,就是在網路上用來傳送 HTML、CSS、JavaScript 等網頁資源的協議。

好像有點明白了,那HTTP是怎麼工作的呢?

HTTP的工作方式很簡單。它的工作流程大概可以概括為以下幾個步驟:
- Client 向 Server 發送一個 HTTP 請求
- Server 收到這個請求後,根據請求的內容進行相應的處理
- Server 向Client 發送一個 HTTP 回應,內容包括請求的結果和相應的資源

好像很簡單,但是我還不是很理解 HTTP 的應用場景。

HTTP的應用場景非常廣泛,它被廣泛地應用在Web應用程式開發、API開發、移動應用程式開發等領域。例如當你在網路上瀏覽網頁、下載文件或者使用 Mobile App 時,都在使用 HTTP Protocol。

什麼是 HTTP 協議

HTTP 指的是超文本傳輸協議,是一種通信協議,用於在網絡上傳輸超文本文檔。HTTP 協議是一種客戶端/伺服器協議,其中客戶端向伺服器發送請求,伺服器返回響應。HTTP 協議是互聯網上應用程式的基礎,包括網站、網頁、應用程式和 API 等等。

HTTP 協議的工作原理

當用戶在瀏覽器中輸入網址或單擊頁面上的鏈接時,瀏覽器就會向伺服器發送 HTTP 請求。HTTP 請求包括請求方法(例如 GET 或 POST)、請求Header和請求主體等信息。伺服器接收到請求後,處理該請求並返回響應。響應包括狀態碼、響應Header和響應主體等信息。瀏覽器接收到響應後,根據響應類型顯示網頁或執行其他操作。

HTTP 協議的版本

HTTP 協議一共有 1.0、1.1 和 2.0 三個版本。HTTP/1.0 是第一個廣泛使用的 HTTP 協議版本,HTTP/1.1 是一個更快、更安全和更可靠的版本,而 HTTP/2 則是一個全新的協議版本,它提供了更快的性能、更好的安全性和更多的功能。

HTTP Request & Response

HTTP 請求由 Request、Request Header 以及 Request Body 三部分組成。請求行包括請求方法、URL 和 HTTP 協議版本等信息。請求Header包括請求者的一些信息,如 User-Agent、Accept-Encoding 和 Accept-Language 等。請求主體通常用於傳輸較大的資料,例如 POST 請求中的表單資料。

HTTP Response 由狀態行、Response Header 和 Response 主體三部分組成。狀態行包括 HTTP 協議版本、狀態碼和狀態消息等信息。Reponse Header 包括 Content-Type、Content-Length 和 Server 等資訊。Response Body 包含伺服器返回的資料,例如 HTML Page 或 JSON Data。

HttpRequest

GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1

HttpResponse

HTTP/1.1 200 OK
Date: Tue, 15 Mar 2022 08:12:31 GMT
Server: Apache/2.4.18 (Ubuntu)
Last-Modified: Fri, 11 Mar 2022 10:30:00 GMT
ETag: "384-5f718247ae380-gzip"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 270
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

<!DOCTYPE html>
<html>
<head>
	<title>歡迎來到我的網站</title>
</head>
<body>
	<h1>歡迎來到我的網站</h1>
	<p>這是一個範例網站</p>
</body>
</html>

HTTP 協議的優點和缺點

HTTP 協議的優點是它是一個標準的客戶端/伺服器協議,易於實現和使用。它支持多種請求方法,例如 GET、POST、PUT 和 DELETE,使開發人員能夠創建各種不同類型的應用程式。此外,HTTP 協議還支持輕量級的傳輸格式,例如 JSON 和 XML。

然而,HTTP 協議也有一些缺點。例如,它是一個無狀態協議,因此它無法保持客戶端和伺服器之間的狀態信息。這使得處理某些任務,例如保持用戶登錄狀態,變得更加困難。此外,HTTP 協議還可能存在安全性問題,例如中間人攻擊和 CSRF 攻擊等。

什麼是 HTTP 狀態碼?

HTTP 狀態碼是伺服器返回給客戶端的一個三位數字代碼,它表示伺服器對請求的處理結果。例如,200 狀態碼表示請求成功,404 狀態碼表示未找到所請求的資源,而 500 狀態碼表示伺服器內部錯誤。

狀態碼 說明
200 請求成功
201 已創建
204 無內容
301 永久重新導向
302 臨時重新導向
304 葉面未修改
400 請求無效
401 未授權
403 禁止訪問
404 找不到網頁
500 內部服務器錯誤
502 閘道錯誤
503 服務器不可用
504 閘道逾時

什麼是 HTTP Header?

HTTP Header是客戶端和伺服器之間進行通信時包含的元資料。它們包含諸如 User-Agent、Content-Type 和 Cookie 等信息,以及一些用於控制快取、跨域和安全性等方面的指令。

Header 說明
Accept 指定客戶端接受哪些類型的資源
Accept-Encoding 指定客戶端可以接受的編碼方式
Cache-Control 控制快取的行為
Content-Type 資源的類型,如 text/html 或 image/jpeg 等
Cookie 請求中包含的 cookie
Host 請求的主機名稱或 IP 地址
User-Agent 客戶端的類型,如瀏覽器、手機 App 等
If-Modified-Since 告知伺服器上次取得資源的時間,用於條件 GET 請求
Referer 表示請求的來源,一般用於防盜鏈等
Authorization 用於在請求中傳遞身份驗證資訊,如 OAuth、JWT 等
Content-Length 資源內容的大小,一般用於 PUT、POST 請求等
If-None-Match ETag 標籤,用於條件 GET 請求,檢查資源是否修改
Connection 用於指定持久連線或非持久連線,一般用於 HTTP/1.1 協議
Header 名稱 說明
X-AspNet-Version 標示使用的 ASP.NET 版本
X-AspNetMvc-Version 標示使用的 ASP.NET MVC 版本
X-Frame-Options 防止 Clickjacking 攻擊,指定網頁是否允許在 iframe 中顯示
X-Xss-Protection 防止跨站腳本攻擊,指定瀏覽器是否啟用 XSS 防護機制
X-Content-Type-Options 防止 MIME Sniffing 攻擊,指定瀏覽器是否應該優先使用 Content-Type 中的 MIME 類型
X-Download-Options 指定檔案下載的行為
X-Powered-By 標示網站所使用的技術和服務器類型等資訊
Server 標示伺服器的類型和版本

Content Disposition

Content Disposition Header 是一個 HTTP 回應的 Header,用來指示如何處理回應的內容。這個 Header 最常用的用途是指定下載檔案的行為。

Content Disposition Header 的值通常是一個字串,包含兩個部分:type 和 filename。其中,type 可以是 inline 或 attachment,filename 則是指定下載檔案時的檔案名稱。

如果 type 為 inline,則瀏覽器會在網頁中顯示回應的內容;如果 type 為 attachment,則瀏覽器會提示使用者下載檔案,並使用 filename 指定檔案名稱。如果沒有指定 filename,則瀏覽器會使用預設的檔案名稱,通常是回應的 URL 中的檔案名稱。

Content Disposition Header 的使用對於網站的檔案下載功能非常重要,可以讓使用者更清楚地知道如何下載檔案,也可以提高下載的安全性。不過,開發人員需要注意檔案名稱的安全性,以免被攻擊者利用漏洞進行攻擊。

以下是 Content Disposition Header 的範例:

Content-Disposition: attachment; filename="example.pdf"

這個 Header 表示回應的內容應該被當作下載檔案來處理,檔案名稱應該是 "example.pdf"。這樣使用者在下載這個檔案時,瀏覽器會提示使用者下載並儲存檔案,檔案名稱也會是 "example.pdf"。如果 type 為 inline,則 Header 會是以下的格式:

Content-Disposition: inline; filename="example.pdf"

這個 Header 表示回應的內容應該在網頁中直接顯示,檔案名稱也應該是 "example.pdf"。這樣使用者在瀏覽網頁時,檔案內容會直接在網頁中顯示,而不需要下載檔案。

HTTP Header Content Disposition

小結

HTTP 協議是 Web 開發中不可或缺的一部分,每個開發人員都應該掌握其基本概念和使用方法。了解 HTTP 請求和響應、HTTP 協議的優點和缺點以及常見問題可以幫助開發人員更好地設計和開發 Web 應用程式。此外,隨
著 HTTP/2 和其他新技術的出現,開發人員應該繼續學習和更新自己的知識。

延伸問題

什麼是 RESTful API

RESTful API 是一種基於 HTTP 協議設計的 API,它使用 HTTP 請求方法(GET、POST、PUT、DELETE 等)來操作資源。RESTful API 的優點是它可以簡化 API 設計和使用,並提高 API 的可靠性和可擴展性。

HTTP/2 的主要改進是什麼

HTTP/2 的主要改進是它使用單個 TCP 連接來處理多個 HTTP 請求。這消除了 HTTP/1.x 中存在的一些性能瓶頸,例如 TCP 建立和關閉延遲以及 HTTP 頭信息的重複傳輸等。此外,HTTP/2 還支持二進制協議,這可以更好地壓縮和傳輸資料,從而提高性能和安全性。

什麼是 HTTP/1.x 和 HTTP/2

HTTP/1.x 和 HTTP/2 都是 HTTP 協議的版本。HTTP/1.x 是一個無狀態協議,它使用明文文本來傳輸資料。HTTP/2 則支持二進制協議和單一 TCP 連接,從而提高性能和安全性。

HTTP 協議的安全性如何

HTTP 協議本身不是一個安全協議,因為它的資料傳輸是明文的,容易受到中間人攻擊和 CSRF 攻擊等。為了保護資料的安全性,可以使用 HTTPS 協議來加密通信,從而防止資料被竊聽和篡改。

HTTP 和 HTTPS 有什麼區別

HTTP 和 HTTPS 都是用於在客戶端和伺服器之間進行通信的協議,但是它們之間有一個主要的區別:HTTPS 使用了 SSL/TLS 協議來加密通信,從而保護資料的安全性,而 HTTP 則沒有這種保護。

HTTP/2 的主要優點是什麼

HTTP/2 的主要優點包括:支持二進制協議、多路複用、伺服器推送和優化效能等。這些功能使得 HTTP/2 能夠更好地壓縮和傳輸資料,提高 Web 應用程式的性能和安全性。

HTTP 協議有哪些常見的問題

HTTP 協議的常見問題包括:明文傳輸容易受到攻擊、資料傳輸速度較慢、無法處理大量請求等。因為這些問題才衍生出後續的 HTTPS Protocol 以及 HTTP/2 Protocol 等技術 😀

Coding

以下是分別示範如何使用 PowerShell、Curl、C# 和 Python 發出 HTTP Request 的範例。

PowerShell

# GET Request
Invoke-WebRequest -Uri "https://www.example.com" -Method GET

# POST Request
Invoke-WebRequest -Uri "https://www.example.com"
  -Method POST -Body @{username="user1"; password="pass1"} -ContentType "application/json"

Curl

# GET Request
curl https://www.example.com

# POST Request
curl -X POST https://www.example.com 
  -H "Content-Type: application/json" -d '{"username": "user1", "password": "pass1"}'

C#

using var client = new HttpClient();

// GET Request
HttpResponseMessage response = await client.GetAsync("https://www.example.com");

// POST Request
var content = new StringContent(
  "{\"username\":\"user1\",\"password\":\"pass1\"}", 
  System.Text.Encoding.UTF8, 
  "application/json");

HttpResponseMessage response = await client.PostAsync("https://www.example.com", content);

Python

import requests

# GET Request
response = requests.get("https://www.example.com")

# POST Request
payload = {"username": "user1", "password": "pass1"}
response = requests.post("https://www.example.com", json=payload)