Nginx 重新導向設定教學
Nginx 是最廣泛部署的網頁伺服器之一,重新導向設定是日常維運的一部分。兩個主要工具 — return 和 rewrite — 經常被混淆,導致效率低下或設定錯誤。
return vs rewrite
return(建議使用)
return 301 https://example.com;
- ✅ 快速 — 直接發送 HTTP 回應,不需要正規表示式引擎
- ✅ 語法簡單,不容易出錯
- ✅ 大多數重新導向場景的官方建議
- ❌ 無法擷取和重複使用網址片段
rewrite(功能強大但較慢)
rewrite ^/old-path/(.*)$ /new-path/$1 permanent;
- ✅ 支援正規表示式擷取群組
- ✅ 可以轉換網址結構
- ❌ 比
return慢 - ❌ 語法複雜,容易造成無限迴圈
💡 經驗法則
盡可能使用 return。只有在需要正規表示式擷取群組或複雜網址轉換時才使用 rewrite。
基本範例
301 永久重新導向
server {
listen 80;
server_name old-domain.com;
return 301 https://new-domain.com$request_uri;
}
302 暫時重新導向
server {
listen 80;
server_name example.com;
location /maintenance {
return 302 /maintenance.html;
}
}
單頁重新導向
location = /old-page.html {
return 301 /new-page.html;
}
HTTP 轉 HTTPS
建議:使用獨立的 server 區塊
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# 網站設定...
}
⚠️ 避免使用 if 指令
Nginx 社群有句話:「if 是邪惡的」。if 指令在某些情境下可能導致非預期行為。HTTPS 重新導向請使用獨立的 server 區塊。
www 正規化
非 www → www
server {
listen 80;
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
return 301 https://www.example.com$request_uri;
}
www → 非 www
server {
listen 80;
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
return 301 https://example.com$request_uri;
}
路徑重新導向
# 重新導向目錄,移除前綴
location /blog/ {
rewrite ^/blog/(.*)$ /articles/$1 permanent;
}
# 使用 map 進行大量重新導向(適合大型清單)
map $uri $new_uri {
/old-page-1 /new-page-1;
/old-page-2 /new-page-2;
}
server {
if ($new_uri) { return 301 $new_uri; }
}
正規表示式重新導向
# 移除 .html 副檔名
location ~ ^(.+)\.html$ {
return 301 $1;
}
# 移除網址中的日期前綴
location ~ ^/\d{4}/\d{2}/\d{2}/(.+)$ {
return 301 /$1;
}
常見陷阱
1. rewrite 迴圈
# ❌ 無限迴圈
location /old/ {
rewrite ^/old/(.*)$ /new/$1;
}
# ✅ 使用 permanent 旗標或 return
location /old/ {
return 301 /new$request_uri;
}
2. 查詢字串遺失
# ❌ 查詢字串被丟棄
location /old { return 301 /new; }
# ✅ 保留查詢字串
location /old { return 301 /new$is_args$args; }
3. HTTPS 目標缺少 SSL 設定
如果您將 HTTP 重新導向到 HTTPS,但尚未在 HTTPS server 區塊中設定有效憑證,使用者會收到連線錯誤。啟用重新導向前,請務必確認 HTTPS 區塊存在且憑證有效。
效能建議
- 優先使用
return而非rewrite— 沒有正規表示式引擎的額外開銷 - 縮短重新導向鏈路:直接從 A 導向 C,而非 A → B → C
- 大型重新導向表使用
map— 在設定載入時計算,而非每次請求 - 避免在
location區塊中使用不必要的正規表示式;盡可能使用前綴或精確匹配 - 變更後務必執行
nginx -t,在重新載入前捕捉語法錯誤
設定重新導向後,使用 301check.com 驗證。