回應 Headers 全解析:伺服器的回話方式
上一篇我們學習了請求 Headers,本篇將聚焦於回應 Headers——伺服器用來告訴客戶端「我是誰、回應內容是什麼、你該怎麼處理它」的關鍵資訊。
一、 回應 Headers 分類
二、 內容描述標頭
2.1 Content-Type
用途:告訴客戶端回應 Body 的格式
Content-Type: application/json; charset=utf-8
Content-Type: text/html; charset=utf-8
Content-Type: image/png常見值:
| Content-Type | 用途 |
|---|---|
text/html | HTML 網頁 |
text/css | CSS 樣式表 |
text/javascript | JavaScript |
application/json | JSON 資料 |
application/xml | XML 資料 |
image/png, image/jpeg, image/webp | 圖片 |
application/pdf | PDF 文件 |
application/octet-stream | 二進位資料(通常觸發下載) |
IMPORTANT
正確設置 Content-Type 很重要!如果設錯,瀏覽器可能無法正確解析內容,甚至引發安全問題。
2.2 Content-Length
用途:指定回應 Body 的大小(bytes)
Content-Length: 1234作用:
- 客戶端知道何時接收完成
- 進度條顯示(下載百分比)
- 檢測傳輸中斷
2.3 Content-Encoding
用途:指定回應 Body 的壓縮方式
Content-Encoding: gzip
Content-Encoding: br壓縮流程:
2.4 Content-Disposition
用途:控制內容的呈現方式
Content-Disposition: inline
Content-Disposition: attachment; filename="report.pdf"
Content-Disposition: attachment; filename*=UTF-8''%E5%A0%B1%E5%91%8A.pdf| 值 | 行為 |
|---|---|
inline | 在瀏覽器中直接顯示 |
attachment | 觸發下載對話框 |
filename | 指定下載檔名 |
filename* | UTF-8 編碼的檔名(支援中文) |
三、 快取控制標頭
3.1 Cache-Control
用途:控制快取策略(回應端)
Cache-Control: public, max-age=31536000
Cache-Control: private, no-cache
Cache-Control: no-store常用指令:
| 指令 | 說明 |
|---|---|
public | 可被任何快取儲存(CDN、代理) |
private | 只能被瀏覽器快取(不給 CDN) |
max-age=<秒> | 資源的新鮮時間 |
s-maxage=<秒> | 共享快取(CDN)的新鮮時間 |
no-cache | 可快取,但每次使用前需重新驗證 |
no-store | 完全不快取(敏感資料用) |
must-revalidate | 過期後必須重新驗證 |
immutable | 資源永不改變(搭配版本號) |
常見策略:
# 靜態資源(JS/CSS/圖片),帶版本號
Cache-Control: public, max-age=31536000, immutable
# HTML 頁面
Cache-Control: no-cache
# API 回應(動態資料)
Cache-Control: private, no-store
# 敏感資料(銀行、個資)
Cache-Control: no-store, no-cache, must-revalidate3.2 ETag
用途:資源的唯一識別碼(指紋)
ETag: "abc123"
ETag: W/"abc123"| 類型 | 格式 | 說明 |
|---|---|---|
| 強 ETag | "abc123" | 位元組完全相同 |
| 弱 ETag | W/"abc123" | 語意相同即可 |
協商流程:
3.3 Last-Modified
用途:資源的最後修改時間
Last-Modified: Wed, 08 Jan 2025 10:30:00 GMT與 ETag 的比較請參考上一篇的說明。
3.4 Expires(較舊)
用途:指定資源的過期時間(HTTP/1.0 遺留)
Expires: Thu, 01 Jan 2026 00:00:00 GMT> `Cache-Control: max-age` 優先級高於 `Expires`。現代應用建議使用 Cache-Control。
3.5 Vary
用途:告訴快取,根據哪些請求標頭來區分快取版本
Vary: Accept-Encoding
Vary: Accept-Language, User-Agent使用情境:
- 同一 URL,根據
Accept-Encoding返回壓縮或未壓縮版本 - 同一 URL,根據
Accept-Language返回不同語言版本
四、 Cookie 相關標頭
4.1 Set-Cookie
用途:讓伺服器在客戶端設置 Cookie
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=Strict
Set-Cookie: user_pref=dark; Max-Age=31536000屬性詳解:
| 屬性 | 說明 | 範例 |
|---|---|---|
Path | Cookie 作用路徑 | Path=/api |
Domain | Cookie 作用域名 | Domain=.example.com |
Max-Age | 存活秒數 | Max-Age=3600 |
Expires | 過期時間點 | Expires=Thu, 01 Jan 2026... |
HttpOnly | JavaScript 無法存取 | 防 XSS |
Secure | 只在 HTTPS 發送 | 防竊聽 |
SameSite | 跨站限制 | Strict, Lax, None |
SameSite 策略:
| 值 | 行為 |
|---|---|
Strict | 完全不允許跨站發送 |
Lax | 導航到目標網站的 GET 請求可發送 |
None | 允許跨站發送(必須搭配 Secure) |
安全 Cookie 範例:
Set-Cookie: session=abc; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=3600五、 重導向標頭
5.1 Location
用途:指定重導向的目標 URL
HTTP/1.1 301 Moved Permanently
Location: https://www.example.com/new-page
HTTP/1.1 302 Found
Location: /login
HTTP/1.1 201 Created
Location: /api/users/123搭配的狀態碼:
| 狀態碼 | 說明 |
|---|---|
301 | 永久重導向(可快取) |
302 | 臨時重導向(不快取) |
303 | POST 後重導向到 GET |
307 | 臨時重導向(保持方法) |
308 | 永久重導向(保持方法) |
201 | 創建成功,Location 指向新資源 |
六、 安全相關標頭
6.1 Strict-Transport-Security (HSTS)
用途:強制瀏覽器使用 HTTPS
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload| 指令 | 說明 |
|---|---|
max-age | HSTS 有效期(秒) |
includeSubDomains | 包含所有子網域 |
preload | 申請加入瀏覽器預載清單 |
TIP
HSTS 可防禦 SSL Strip 攻擊,詳情請參考 SSL Strip 專題。
6.2 X-Content-Type-Options
用途:禁止瀏覽器猜測 MIME 類型
X-Content-Type-Options: nosniff為什麼重要?
瀏覽器可能會「嗅探」內容類型,把明文當作 JavaScript 執行。這個標頭強制瀏覽器只接受正確的 Content-Type。
6.3 X-Frame-Options
用途:防止網頁被嵌入 iframe(防 Clickjacking)
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN| 值 | 說明 |
|---|---|
DENY | 完全禁止被嵌入 |
SAMEORIGIN | 只允許同源嵌入 |
6.4 Content-Security-Policy (CSP)
用途:限制資源載入來源,防止 XSS
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'常用指令:
| 指令 | 說明 |
|---|---|
default-src | 預設來源 |
script-src | JavaScript 來源 |
style-src | CSS 來源 |
img-src | 圖片來源 |
connect-src | API 請求來源 |
frame-ancestors | 可嵌入此頁面的來源 |
6.5 X-XSS-Protection(已過時)
X-XSS-Protection: 1; mode=blockWARNING
此標頭已過時,現代瀏覽器建議改用 CSP。但為了相容舊瀏覽器,仍可設置。
6.6 Referrer-Policy
用途:控制 Referer 標頭的洩漏程度
Referrer-Policy: strict-origin-when-cross-origin| 值 | 行為 |
|---|---|
no-referrer | 完全不發送 Referer |
origin | 只發送 scheme + host |
same-origin | 只對同源發送 |
strict-origin-when-cross-origin | 跨域時只發送 origin |
七、 CORS 相關標頭
7.1 Access-Control-Allow-Origin
用途:允許哪些來源進行跨域請求
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Origin: *CAUTION
使用 * 時不能搭配 credentials: true,必須指定具體來源。
7.2 Access-Control-Allow-Methods
用途:允許的 HTTP 方法
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS7.3 Access-Control-Allow-Headers
用途:允許的請求標頭
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With7.4 Access-Control-Allow-Credentials
用途:是否允許攜帶 Cookie
Access-Control-Allow-Credentials: true7.5 Access-Control-Max-Age
用途:預檢請求結果的快取時間
Access-Control-Max-Age: 864007.6 Access-Control-Expose-Headers
用途:允許 JavaScript 讀取的回應標頭
Access-Control-Expose-Headers: X-Request-ID, X-RateLimit-Remaining預設只有以下標頭可被 JavaScript 讀取:
Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
八、 伺服器資訊標頭
8.1 Server
用途:伺服器軟體資訊
Server: nginx/1.18.0
Server: Apache/2.4.41WARNING
暴露版本號可能增加安全風險,建議在生產環境隱藏或簡化。
8.2 Date
用途:回應產生的時間
Date: Wed, 08 Jan 2025 10:30:00 GMT8.3 X-Request-ID
用途:請求追蹤 ID
X-Request-ID: 550e8400-e29b-41d4-a716-446655440000便於除錯和日誌關聯。
8.4 X-RateLimit-*
用途:API 頻率限制資訊
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704700800總結
| 類別 | 常用標頭 | 主要用途 |
|---|---|---|
| 內容 | Content-Type, Content-Length, Content-Disposition | 描述回應 Body |
| 快取 | Cache-Control, ETag, Last-Modified, Vary | 控制快取行為 |
| Cookie | Set-Cookie | 設置客戶端 Cookie |
| 重導向 | Location | 指定跳轉目標 |
| 安全 | HSTS, CSP, X-Content-Type-Options | 增強安全性 |
| CORS | Access-Control-* | 跨域存取控制 |
| 伺服器 | Server, Date, X-Request-ID | 伺服器資訊 |
進階挑戰
- 配置一個完整的安全標頭組合(HSTS + CSP + X-Content-Type-Options + X-Frame-Options),並使用 securityheaders.com 檢測你的網站。
- 設計一個 API 的快取策略:列表頁、詳情頁、用戶資料分別應該使用什麼 Cache-Control?
- 思考:為什麼
Set-Cookie的HttpOnly屬性對防禦 XSS 很重要?在什麼情況下你可能不想使用它?