請求 Headers 全解析:HTTP 請求的元資訊
HTTP Headers 是請求和回應中攜帶的「元資料」,它們告訴伺服器如何處理請求,以及客戶端期望什麼樣的回應。本篇將深入解析請求中最常用的 Headers。
一、 Headers 基礎
1.1 格式規範
每個 Header 由名稱和值組成,以冒號分隔:
Header-Name: Header-Value格式規則:
| 規則 | 說明 |
|---|---|
| 名稱大小寫 | 不區分大小寫(Content-Type = content-type) |
| 冒號位置 | 名稱與冒號之間不能有空格 |
| 值前空格 | 值前可以有一個空格(慣例) |
| 多值語法 | 某些 Headers 可用逗號分隔多個值 |
1.2 請求 Headers 分類
二、 必要標頭
2.1 Host
用途:指定請求的目標主機名稱和埠號
Host: api.example.com
Host: api.example.com:8080為什麼重要?
- HTTP/1.1 中唯一必填的請求標頭
- 允許同一個 IP 位址託管多個網站(虛擬主機)
- 沒有 Host,伺服器不知道你要訪問哪個網站
WARNING
缺少 Host 標頭會導致 400 Bad Request 錯誤。
三、 內容相關標頭
3.1 Content-Type
用途:告訴伺服器請求 Body 的格式
Content-Type: application/json
Content-Type: application/x-www-form-urlencoded
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary常見值:
| Content-Type | 用途 | 範例資料 |
|---|---|---|
application/json | JSON 格式(API 主流) | {"name": "John"} |
application/x-www-form-urlencoded | 表單預設格式 | name=John&age=30 |
multipart/form-data | 檔案上傳 | 多部分資料 |
text/plain | 純文字 | Hello World |
application/xml | XML 格式 | <user><name>John</name></user> |
JavaScript 範例:
// JSON 格式
fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "John" }),
});
// 表單格式
fetch("/api/login", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "username=john&password=secret",
});3.2 Content-Length
用途:指定請求 Body 的大小(bytes)
Content-Length: 42注意事項:
- 大多數 HTTP 客戶端會自動計算
- 如果值與實際大小不符,可能導致截斷或錯誤
- 使用
Transfer-Encoding: chunked時不需要此標頭
3.3 Content-Encoding
用途:指定請求 Body 的壓縮方式
Content-Encoding: gzip
Content-Encoding: brNOTE
請求 Body 壓縮較少見,通常用於回應。但某些 API 接受壓縮的請求 Body 以節省頻寬。
四、 內容協商標頭 (Accept-*)
內容協商讓客戶端告訴伺服器:「我能接受什麼格式的回應?」
4.1 Accept
用途:指定客戶端可接受的回應內容類型
Accept: application/json
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8品質值 (Quality Value):
q參數表示偏好程度(0.0 ~ 1.0)- 預設值為 1.0
- 伺服器應優先返回高品質值的格式
Accept: application/json, text/html;q=0.9, */*;q=0.1解讀:
- 最想要
application/json(q=1.0) - 其次
text/html(q=0.9) - 其他格式也可以(q=0.1)
4.2 Accept-Language
用途:指定偏好的回應語言
Accept-Language: zh-TW, zh;q=0.9, en-US;q=0.8, en;q=0.7解讀:
- 優先繁體中文(台灣)
- 其次任何中文
- 再來美式英文
- 最後任何英文
4.3 Accept-Encoding
用途:指定客戶端支援的壓縮演算法
Accept-Encoding: gzip, deflate, br| 演算法 | 說明 |
|---|---|
gzip | 最廣泛支援 |
deflate | 較舊的壓縮方式 |
br | Brotli,壓縮率更高 |
identity | 不壓縮 |
4.4 Accept-Charset
用途:指定可接受的字符編碼(現代較少使用)
Accept-Charset: utf-8, iso-8859-1;q=0.5TIP
現代 Web 幾乎都使用 UTF-8,這個標頭已較少使用。
五、 認證與授權標頭
5.1 Authorization
用途:攜帶認證憑證
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=常見認證方案:
| 方案 | 格式 | 用途 |
|---|---|---|
Bearer | Bearer <token> | JWT、OAuth 2.0 Access Token |
Basic | Basic <base64(user:pass)> | 基本認證(較不安全) |
Digest | Digest ... | 摘要認證 |
ApiKey | ApiKey <key> | API 金鑰(非標準但常見) |
Bearer Token 範例:
fetch("/api/protected", {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});> **Basic 認證**會將使用者名稱和密碼以 Base64 編碼傳輸,這只是編碼而非加密!必須搭配 HTTPS 使用。
5.2 Cookie
用途:攜帶客戶端儲存的 Cookie
Cookie: session_id=abc123; user_pref=dark_mode特點:
- 多個 Cookie 用分號分隔
- 瀏覽器會自動發送符合條件的 Cookie
- 可包含 Session ID、偏好設定等
與 Authorization 的差異:
| 面向 | Cookie | Authorization |
|---|---|---|
| 自動發送 | ✅ 瀏覽器自動處理 | ❌ 需手動設定 |
| 跨域 | 受 SameSite 限制 | 不受限制 |
| 儲存方式 | 瀏覽器自動儲存 | 需手動儲存(localStorage 等) |
| 適用場景 | 傳統網站 Session | API Token 認證 |
六、 快取與條件請求標頭
6.1 Cache-Control
用途:控制快取行為(請求端)
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: max-age=0請求端指令:
| 指令 | 說明 |
|---|---|
no-cache | 強制向伺服器驗證 |
no-store | 不使用任何快取 |
max-age=0 | 視為已過期,需重新驗證 |
max-stale=<秒> | 可接受過期一段時間的快取 |
min-fresh=<秒> | 需要至少還能新鮮一段時間 |
6.2 If-Modified-Since
用途:條件請求,只在資源有更新時才下載
If-Modified-Since: Wed, 08 Jan 2025 10:00:00 GMT流程:
6.3 If-None-Match
用途:條件請求,基於 ETag 驗證
If-None-Match: "abc123"
If-None-Match: "abc123", "def456"ETag vs Last-Modified:
| 比較 | ETag | Last-Modified |
|---|---|---|
| 精確度 | 位元組級別 | 秒級別 |
| 適用場景 | 內容散列 | 修改時間 |
| 優先級 | 較高 | 較低 |
七、 客戶端資訊標頭
7.1 User-Agent
用途:識別客戶端軟體
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36解析:
Mozilla/5.0 ← 相容性標識
(Macintosh; Intel Mac OS X) ← 作業系統
AppleWebKit/537.36 ← 瀏覽器引擎
Chrome/120.0.0.0 ← 瀏覽器名稱與版本
Safari/537.36 ← 相容性標識常見用途:
- 統計分析(瀏覽器市佔率)
- 回應不同裝置(桌面 vs 行動版)
- 反爬蟲偵測
WARNING
User-Agent 很容易被偽造,不應用於安全相關的判斷。
7.2 Referer
用途:告知伺服器請求的來源頁面
Referer: https://www.google.com/search?q=http+headersNOTE
這是一個歷史性的拼寫錯誤(正確應為 Referrer),但為了相容性保留了下來。
用途:
- 流量分析(從哪裡來)
- 防盜鏈(限制圖片只能在特定網站顯示)
- CSRF 防護的參考(但不可靠)
隱私考量:
現代瀏覽器會根據 Referrer-Policy 限制資訊洩漏:
Referrer-Policy: strict-origin-when-cross-origin7.3 Origin
用途:指示請求的來源(Scheme + Host + Port)
Origin: https://www.example.com與 Referer 的差異:
| 比較 | Origin | Referer |
|---|---|---|
| 包含路徑 | ❌ 只有 scheme + host + port | ✅ 包含完整 URL |
| 何時發送 | CORS 請求、POST 請求 | 大多數導航與資源請求 |
| 隱私保護 | 較好(不洩漏路徑) | 可能洩漏敏感路徑 |
八、 CORS 相關標頭
8.1 Access-Control-Request-Method
用途:預檢請求時,告知伺服器實際請求會使用的方法
Access-Control-Request-Method: POST8.2 Access-Control-Request-Headers
用途:預檢請求時,告知伺服器實際請求會攜帶的自訂標頭
Access-Control-Request-Headers: Content-Type, Authorization完整預檢請求範例:
OPTIONS /api/users HTTP/1.1
Host: api.example.com
Origin: https://www.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization九、 其他常用標頭
9.1 X-Requested-With
用途:標識 AJAX 請求(非標準但廣泛使用)
X-Requested-With: XMLHttpRequestjQuery 等框架會自動添加此標頭,伺服器可用來區分 AJAX 與普通請求。
9.2 X-Forwarded-For
用途:在代理伺服器後,傳遞原始客戶端 IP
X-Forwarded-For: 203.0.113.195, 70.41.3.18, 150.172.238.178格式:<client>, <proxy1>, <proxy2>
CAUTION
此標頭容易被偽造,不應直接用於安全判斷。
9.3 X-Request-ID
用途:追蹤請求,方便除錯與日誌關聯
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000總結
| 類別 | 常用標頭 | 主要用途 |
|---|---|---|
| 必要 | Host | 指定目標主機 |
| 內容 | Content-Type, Content-Length | 描述請求 Body |
| 協商 | Accept, Accept-Language, Accept-Encoding | 告知偏好格式 |
| 認證 | Authorization, Cookie | 身份驗證 |
| 快取 | Cache-Control, If-Modified-Since, If-None-Match | 控制快取行為 |
| 來源 | User-Agent, Referer, Origin | 客戶端資訊 |
| CORS | Access-Control-Request-* | 跨域請求協商 |
進階挑戰
- 使用瀏覽器 DevTools 觀察一個網站的請求,記錄至少 10 個不同的請求標頭,並解釋每個的用途。
- 嘗試用 cURL 發送一個請求,手動設定
Accept-Language為日文,觀察回應有何不同。 - 思考:為什麼
Authorization: Bearer <token>比Cookie更適合 API 認證?在什麼情況下 Cookie 反而更適合?