目錄
02-1. HTTP 基礎概念
⏱️ 閱讀時間: 10 分鐘 🎯 難度: ⭐⭐ (簡單)
🎯 本篇重點
理解 HTTP 協定的基本概念、運作原理、版本演進,以及為什麼 HTTP 是網路世界最重要的協定。
🤔 什麼是 HTTP?
HTTP (HyperText Transfer Protocol) = 超文本傳輸協定
一句話解釋: HTTP 就像是瀏覽器和網站伺服器之間的「對話語言」,規定了雙方如何請求和傳送網頁資料。
📖 用圖書館借書來比喻 HTTP
借書流程 = HTTP 請求流程
你(瀏覽器) → 圖書館(伺服器)
步驟 1:你走進圖書館(建立 TCP 連線)
步驟 2:你填寫借書單(HTTP 請求)
- 書名:《三國演義》(URL)
- 借書方式:借閱(GET 方法)
步驟 3:館員處理(伺服器處理請求)
- 檢查有沒有這本書
- 檢查你有沒有借書資格
步驟 4:館員回應(HTTP 回應)
- 成功:給你書 + 借書證明(200 OK + 內容)
- 失敗:書不存在(404 Not Found)
- 失敗:沒有權限(403 Forbidden)
步驟 5:你離開圖書館(關閉 TCP 連線)🏗️ HTTP 在網路模型中的位置
OSI 7 層模型
┌──────────────────────────────┬─────────────────┐
│ 7. Application Layer (應用層) │ HTTP, HTTPS │ ← HTTP 在這裡
├──────────────────────────────┼─────────────────┤
│ 6. Presentation Layer (表示層)│ 加密、壓縮 │
├──────────────────────────────┼─────────────────┤
│ 5. Session Layer (會話層) │ 建立、維護會話 │
├──────────────────────────────┼─────────────────┤
│ 4. Transport Layer (傳輸層) │ TCP │
├──────────────────────────────┼─────────────────┤
│ 3. Network Layer (網路層) │ IP │
├──────────────────────────────┼─────────────────┤
│ 2. Data Link Layer (資料鏈結層)│ Ethernet │
├──────────────────────────────┼─────────────────┤
│ 1. Physical Layer (實體層) │ 網路線、光纖 │
└──────────────────────────────┴─────────────────┘HTTP 位於第 7 層(應用層)
- HTTP 是應用層協定
- 提供網頁資料傳輸服務
- 使用者透過瀏覽器與 Web 伺服器互動
TCP/IP 4 層模型
┌─────────────────────────────┬─────────────────┐
│ 4. Application Layer (應用層) │ HTTP, HTTPS │ ← HTTP 在這裡
├─────────────────────────────┼─────────────────┤
│ 3. Transport Layer (傳輸層) │ TCP │
├─────────────────────────────┼─────────────────┤
│ 2. Internet Layer (網際網路層)│ IP │
├─────────────────────────────┼─────────────────┤
│ 1. Network Access (網路存取層)│ Ethernet │
└─────────────────────────────┴─────────────────┘HTTP 位於第 4 層(應用層)
- 在 TCP/IP 模型中,HTTP 同樣是應用層協定
- 使用 TCP 作為傳輸層協定(Port 80)
- TCP 提供可靠的連線導向傳輸
對比表:
| 模型 | HTTP 所在層級 | 層級編號 | 底層協定 | Port |
|---|---|---|---|---|
| OSI 7 層 | Application Layer | Layer 7 | TCP (Layer 4) | 80 |
| TCP/IP 4 層 | Application Layer | Layer 4 | TCP (Layer 3) | 80 |
重點:
- HTTP 是應用層協定(兩種模型都是)
- 使用 TCP 作為傳輸層(Port 80,HTTPS 用 Port 443)
- TCP 提供可靠傳輸,HTTP 提供網頁內容傳輸
🌐 HTTP 的基本運作原理
請求-回應模型(Request-Response Model)
【客戶端(瀏覽器)】 【伺服器】
請求(Request)
────────────────────→
GET /index.html HTTP/1.1
Host: www.example.com
處理請求...
回應(Response)
←────────────────────
HTTP/1.1 200 OK
Content-Type: text/html
<html>...</html>HTTP 的特性
1. 無狀態(Stateless)
├─ 每個請求都是獨立的
├─ 伺服器不記得你是誰
└─ 需要 Cookie/Session 來記住用戶
2. 無連線(Connectionless)
├─ 每次請求都建立新連線(HTTP/1.0)
├─ 請求完畢就關閉連線
└─ HTTP/1.1 支援持久連線
3. 基於 TCP
├─ 使用 TCP 作為傳輸層協定
├─ 保證資料可靠傳輸
└─ 預設使用 Port 80(HTTP)、443(HTTPS)
4. 文字協定(Text Protocol)
├─ 請求和回應都是可讀的文字格式
├─ 方便除錯
└─ HTTP/2 改用二進位格式🔍 HTTP 的組成部分
HTTP 請求(Request)
GET /index.html HTTP/1.1 ← 請求行(Request Line)
Host: www.example.com ← 標頭(Headers)
User-Agent: Mozilla/5.0
Accept: text/html
Connection: keep-alive
← 空行
[可選的請求內容] ← 主體(Body)HTTP 回應(Response)
HTTP/1.1 200 OK ← 狀態行(Status Line)
Content-Type: text/html ← 標頭(Headers)
Content-Length: 1234
Server: Apache/2.4
Date: Mon, 06 Jan 2025 12:00:00 GMT
← 空行
<html> ← 主體(Body)
<head><title>首頁</title></head>
<body>Hello World!</body>
</html>📝 HTTP 請求方法
常用方法一覽
GET - 取得資源(讀取)
POST - 新增資源(建立)
PUT - 更新資源(完整更新)
PATCH - 部分更新資源
DELETE - 刪除資源
HEAD - 只取得標頭(不取內容)
OPTIONS - 查詢伺服器支援的方法實際例子
【讀取文章】
GET /articles/123 HTTP/1.1
→ 取得編號 123 的文章
【發表文章】
POST /articles HTTP/1.1
Content-Type: application/json
{"title": "新文章", "content": "內容"}
→ 建立新文章
【更新文章】
PUT /articles/123 HTTP/1.1
Content-Type: application/json
{"title": "修改後的標題", "content": "修改後的內容"}
→ 完整更新編號 123 的文章
【刪除文章】
DELETE /articles/123 HTTP/1.1
→ 刪除編號 123 的文章📊 HTTP 狀態碼
五大類狀態碼
1xx - 資訊性回應(Informational)
├─ 100 Continue
└─ 101 Switching Protocols
2xx - 成功(Success)
├─ 200 OK ← 最常見
├─ 201 Created ← POST 成功建立資源
└─ 204 No Content ← 成功但無內容
3xx - 重新導向(Redirection)
├─ 301 Moved Permanently ← 永久重新導向
├─ 302 Found ← 暫時重新導向
└─ 304 Not Modified ← 使用快取
4xx - 客戶端錯誤(Client Error)
├─ 400 Bad Request ← 請求格式錯誤
├─ 401 Unauthorized ← 需要登入
├─ 403 Forbidden ← 沒有權限
├─ 404 Not Found ← 找不到資源
└─ 429 Too Many Requests ← 請求太頻繁
5xx - 伺服器錯誤(Server Error)
├─ 500 Internal Server Error ← 伺服器內部錯誤
├─ 502 Bad Gateway ← 閘道錯誤
└─ 503 Service Unavailable ← 服務暫時無法使用🚀 HTTP 版本演進
HTTP/0.9(1991 年)
特性:
- 超級簡單,只有 GET 方法
- 沒有標頭(Headers)
- 只能傳輸 HTML
範例:
GET /index.html
(沒有版本號,沒有標頭)HTTP/1.0(1996 年)
新增功能:
✅ 加入版本號(HTTP/1.0)
✅ 加入標頭(Headers)
✅ 加入狀態碼(200, 404, 500...)
✅ 支援多種內容類型(圖片、影片等)
✅ 支援 POST、HEAD 等方法
缺點:
❌ 每個請求都要建立新連線(效率差)
範例:
GET /index.html HTTP/1.0
Host: www.example.com
HTTP/1.0 200 OK
Content-Type: text/html
<html>...</html>HTTP/1.1(1997 年 - 現在最常用)
改進:
✅ 持久連線(Keep-Alive)
- 一個 TCP 連線可以發送多個請求
- 不用每次都重新建立連線
✅ 管線化(Pipelining)
- 可以同時發送多個請求
- 不用等第一個回應回來
✅ 分塊傳輸(Chunked Transfer)
- 可以一邊產生一邊傳送
- 不用等全部內容都產生完
✅ Host 標頭
- 支援虛擬主機
- 一個 IP 可以架多個網站
✅ 快取控制
- Cache-Control 標頭
- 減少重複請求
範例:
GET /index.html HTTP/1.1
Host: www.example.com
Connection: keep-alive ← 持久連線
HTTP/1.1 200 OK
Content-Type: text/html
Connection: keep-aliveHTTP/2(2015 年)
革命性改進:
✅ 二進位格式
- 不再是文字協定
- 效率更高
✅ 多工(Multiplexing)
- 一個連線同時處理多個請求/回應
- 不會互相阻塞
✅ 標頭壓縮(Header Compression)
- 使用 HPACK 演算法
- 減少重複的標頭傳輸
✅ 伺服器推送(Server Push)
- 伺服器主動推送資源
- 不用等客戶端請求
✅ 優先順序(Stream Priority)
- 重要的資源先傳
效能提升:
- 網頁載入速度提升 20-50%HTTP/3(2022 年)
最新版本:
✅ 基於 QUIC 協定
- 不再使用 TCP,改用 UDP
- 更快的連線建立
✅ 改善隊頭阻塞(Head-of-Line Blocking)
- TCP 層的阻塞問題
- 一個封包遺失不影響其他資料流
✅ 更好的行動網路支援
- 切換 Wi-Fi/4G 不斷線
✅ 內建加密
- 強制 TLS 1.3
使用情況:
- Google、Facebook、Cloudflare 已支援
- Chrome、Firefox、Safari 已支援💻 實戰範例:用 Python 發送 HTTP 請求
使用 requests 套件
import requests
# GET 請求
response = requests.get('https://api.github.com/users/octocat')
print(f"狀態碼:{response.status_code}") # 200
print(f"標頭:{response.headers}") # 回應標頭
print(f"內容:{response.text}") # 回應內容
print(f"JSON:{response.json()}") # 解析 JSON
# POST 請求
data = {
'title': '新文章',
'content': '文章內容'
}
response = requests.post(
'https://api.example.com/articles',
json=data,
headers={'Authorization': 'Bearer TOKEN'}
)
print(f"狀態碼:{response.status_code}") # 201 Created
print(f"回應內容:{response.json()}")
# PUT 請求(更新)
update_data = {
'title': '修改後的標題'
}
response = requests.put(
'https://api.example.com/articles/123',
json=update_data
)
# DELETE 請求
response = requests.delete('https://api.example.com/articles/123')
print(f"狀態碼:{response.status_code}") # 204 No Content使用原始的 HTTP 請求(socket)
import socket
# 建立 TCP 連線
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('www.example.com', 80))
# 發送 HTTP 請求
request = """GET / HTTP/1.1
Host: www.example.com
User-Agent: Python/3.9
Accept: text/html
Connection: close
"""
sock.send(request.encode())
# 接收回應
response = b''
while True:
data = sock.recv(4096)
if not data:
break
response += data
sock.close()
# 解析回應
response_text = response.decode()
print(response_text)
# 輸出:
# HTTP/1.1 200 OK
# Content-Type: text/html
# ...
# <html>...</html>🌐 實際應用場景
1. 瀏覽網頁
你在瀏覽器輸入 www.google.com
步驟 1:DNS 解析
www.google.com → 142.250.185.46(IP)
步驟 2:建立 TCP 連線
三次握手 → 連線建立
步驟 3:發送 HTTP 請求
GET / HTTP/1.1
Host: www.google.com
User-Agent: Chrome/120.0
Accept: text/html
步驟 4:接收 HTTP 回應
HTTP/1.1 200 OK
Content-Type: text/html
<html>...</html>
步驟 5:渲染網頁
瀏覽器解析 HTML、CSS、JavaScript → 顯示網頁2. API 呼叫
# 前端 JavaScript 呼叫後端 API
// 取得用戶資料
fetch('https://api.example.com/users/123')
.then(response => response.json())
.then(data => {
console.log(data); // { id: 123, name: "John" }
});
// 更新用戶資料
fetch('https://api.example.com/users/123', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer TOKEN'
},
body: JSON.stringify({
name: 'John Doe',
email: 'john@example.com'
})
})
.then(response => response.json())
.then(data => console.log('更新成功', data));3. 檔案上傳
import requests
# 上傳圖片
files = {'file': open('photo.jpg', 'rb')}
response = requests.post(
'https://api.example.com/upload',
files=files
)
print(response.json()) # { "url": "https://cdn.../photo.jpg" }🤔 為什麼 HTTP 這麼重要?
1. 無所不在
HTTP 無處不在:
├─ 網頁瀏覽(Chrome、Firefox、Safari)
├─ API 呼叫(RESTful API、GraphQL)
├─ 行動應用(App 與後端通訊)
├─ 物聯網(IoT 設備)
├─ 微服務(Service-to-Service)
└─ 雲端服務(AWS、Azure、GCP)
估計:
- 全球每天超過 1000 億次 HTTP 請求
- 99% 的網路流量使用 HTTP/HTTPS2. 簡單易用
優點:
✅ 文字協定(易讀、易除錯)
✅ 無狀態(簡化伺服器設計)
✅ 擴展性強(可以加新的標頭)
✅ 跨平台(任何語言都能實作)
✅ 生態系統完整(大量工具支援)3. 標準化
標準制定:
├─ IETF(Internet Engineering Task Force)
├─ RFC 文件(Request for Comments)
└─ W3C(World Wide Web Consortium)
主要 RFC:
- RFC 7230-7235(HTTP/1.1)
- RFC 7540(HTTP/2)
- RFC 9114(HTTP/3)
好處:
- 所有瀏覽器、伺服器遵循同一標準
- 跨平台互通🎓 面試常見問題
Q1:HTTP 是無狀態的,那怎麼保持登入狀態?
A:使用 Cookie 和 Session
方法 1:Session + Cookie
1. 用戶登入成功
2. 伺服器建立 Session(儲存在伺服器)
3. 伺服器回傳 Session ID(透過 Cookie)
4. 客戶端每次請求都帶上 Cookie
5. 伺服器透過 Session ID 識別用戶
範例:
// 登入請求
POST /login HTTP/1.1
Content-Type: application/json
{"username": "john", "password": "123456"}
// 伺服器回應
HTTP/1.1 200 OK
Set-Cookie: sessionid=abc123; HttpOnly; Secure
// 後續請求自動帶上 Cookie
GET /profile HTTP/1.1
Cookie: sessionid=abc123
方法 2:Token(JWT)
1. 用戶登入成功
2. 伺服器產生 Token(JWT)
3. 客戶端儲存 Token(localStorage)
4. 每次請求在 Authorization 標頭帶上 Token
5. 伺服器驗證 Token
範例:
// 登入請求
POST /login HTTP/1.1
// 伺服器回應
{"token": "eyJhbGci..."}
// 後續請求
GET /profile HTTP/1.1
Authorization: Bearer eyJhbGci...Q2:HTTP/1.1 和 HTTP/2 的最大差異?
A:HTTP/2 使用多工(Multiplexing)
HTTP/1.1 的問題:
- 隊頭阻塞(Head-of-Line Blocking)
- 一個連線一次只能處理一個請求
- 即使使用持久連線,也要等前一個回應完成
範例:
請求 1:GET /style.css → 等待...
請求 2:GET /script.js → 等請求 1 完成
請求 3:GET /image.png → 等請求 2 完成
HTTP/2 的解決:
- 多工:一個連線同時處理多個請求
- 不會互相阻塞
範例:
請求 1:GET /style.css ↓
請求 2:GET /script.js ↓ 同時進行
請求 3:GET /image.png ↓
結果:
- 網頁載入速度提升 20-50%
- 不需要域名分片(Domain Sharding)Q3:為什麼需要 HTTPS?HTTP 有什麼問題?
A:HTTP 是明文傳輸,不安全
HTTP 的三大問題:
1. 竊聽(Eavesdropping)
- 資料以明文傳輸
- 任何人都可以攔截並讀取
- 例:帳號密碼、信用卡資訊
2. 篡改(Tampering)
- 中間人可以修改資料
- 例:植入惡意腳本、修改網頁內容
3. 偽裝(Impersonation)
- 無法驗證伺服器身份
- 例:釣魚網站
HTTPS 的解決:
✅ 加密(Encryption)→ 防止竊聽
✅ 完整性(Integrity)→ 防止篡改
✅ 驗證(Authentication)→ 防止偽裝
使用 SSL/TLS 加密:
- 所有資料加密傳輸
- 使用數位憑證驗證身份
- 確保資料完整性Q4:GET 和 POST 有什麼差異?
A:主要差異在語義、安全性、快取
語義差異:
GET - 取得資源(讀取)
POST - 新增資源(建立)
安全性:
GET:
- 參數在 URL 中(可見)
- 會被記錄在瀏覽器歷史
- 可能洩露敏感資訊
- 例:/login?username=john&password=123
POST:
- 參數在 Body 中(不可見)
- 不會被記錄在瀏覽器歷史
- 相對安全
快取:
GET:
- 可以被快取
- 可以加入書籤
- 適合查詢
POST:
- 通常不被快取
- 不能加入書籤
- 適合修改資料
長度限制:
GET:
- URL 長度有限制(約 2048 字元)
- 大量資料無法傳送
POST:
- 無長度限制
- 可以傳送大量資料
冪等性(Idempotence):
GET - 冪等(多次請求結果相同)
POST - 非冪等(多次請求可能產生多個資源)Q5:HTTP 的 Keep-Alive 是什麼?
A:Keep-Alive = 持久連線(Persistent Connection)
HTTP/1.0:
- 每個請求建立新連線
- 請求完畢就關閉連線
- 效率差
HTTP/1.1:
- 預設使用 Keep-Alive
- 一個 TCP 連線可以發送多個請求
- 不用每次都重新建立連線
範例:
// HTTP/1.0(每次都重新連線)
請求 1 → 建立連線 → GET /page1 → 關閉連線
請求 2 → 建立連線 → GET /page2 → 關閉連線
請求 3 → 建立連線 → GET /page3 → 關閉連線
// HTTP/1.1(Keep-Alive)
建立連線 → GET /page1 → GET /page2 → GET /page3 → 關閉連線
優點:
✅ 減少 TCP 連線建立的開銷(三次握手)
✅ 減少 TCP 連線關閉的開銷(四次揮手)
✅ 提升效能(減少延遲)
設定:
// 伺服器回應
HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: timeout=5, max=100
timeout=5:連線閒置 5 秒後關閉
max=100:最多處理 100 個請求✅ 重點回顧
HTTP 定義:
- 超文本傳輸協定
- 瀏覽器和伺服器之間的對話語言
HTTP 特性:
- ✅ 無狀態(每個請求獨立)
- ✅ 基於 TCP(可靠傳輸)
- ✅ 請求-回應模型
- ✅ 文字協定(HTTP/1.x)
HTTP 組成:
- 請求:請求行 + 標頭 + 主體
- 回應:狀態行 + 標頭 + 主體
HTTP 方法:
- GET(讀取)、POST(新增)、PUT(更新)、DELETE(刪除)
HTTP 狀態碼:
- 2xx(成功)、3xx(重新導向)、4xx(客戶端錯誤)、5xx(伺服器錯誤)
HTTP 版本:
- HTTP/1.1 - 最常用、持久連線
- HTTP/2 - 多工、二進位、標頭壓縮
- HTTP/3 - 基於 QUIC(UDP)、更快
面試重點:
- ✅ HTTP 無狀態 → 用 Cookie/Session/Token 保持狀態
- ✅ HTTP/2 多工 → 解決隊頭阻塞
- ✅ HTTP 不安全 → 用 HTTPS 加密
- ✅ GET vs POST → 語義、安全性、快取
- ✅ Keep-Alive → 持久連線,提升效能
上一篇: 01-4. TCP vs UDP 下一篇: 02-2. HTTP 請求與回應
最後更新:2025-01-06