Apache 重新導向設定教學
Apache 的重新導向主要透過 .htaccess 檔案和 mod_rewrite 模組來設定。這在共享主機環境中特別有用,因為您無法存取主要伺服器設定檔。
.htaccess 基礎
.htaccess 是 Apache 的目錄層級設定檔。將它放在網站根目錄,Apache 會自動讀取。檔名以點開頭 — 在 Unix 系統中是隱藏檔案。
啟用 mod_rewrite
# Ubuntu/Debian
sudo a2enmod rewrite
sudo systemctl restart apache2
# CentOS/RHEL — 在 /etc/httpd/conf/httpd.conf 中取消註解:
LoadModule rewrite_module modules/mod_rewrite.so
允許 .htaccess 覆寫
<Directory /var/www/html>
AllowOverride All
</Directory>
Redirect 指令
最簡單的方式 — 不需要正規表示式:
# 301 永久
Redirect 301 /old-page.html https://example.com/new-page.html
# 302 暫時
Redirect 302 /sale https://example.com/promo
# 整站重新導向到新網域
Redirect 301 / https://new-domain.com/
💡 Redirect 的限制
Redirect 指令簡單但不支援正規表示式或條件邏輯。更複雜的需求請使用 RewriteRule。
RewriteRule
RewriteEngine On
# HTTP → HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# 非 www → www
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
常用旗標
[R=301]— 301 永久重新導向[R=302]— 302 暫時重新導向[L]— 最後一條規則,停止處理[NC]— 不區分大小寫[QSA]— 附加原始查詢字串
RewriteCond
在執行後續 RewriteRule 之前必須為真的條件:
# 重新導向行動裝置使用者
RewriteCond %{HTTP_USER_AGENT} "android|iphone|ipad" [NC]
RewriteRule ^(.*)$ https://m.example.com/$1 [R=302,L]
# 根據查詢字串重新導向
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$
RewriteRule ^article$ /post/%1? [R=301,L]
常見情境
強制 HTTPS + www
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
移除 .html 副檔名
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.+)$ $1.html [L]
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /(.+)\.html
RewriteRule ^ /%1 [R=301,L]
WordPress 永久連結
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
常見陷阱
500 Internal Server Error
幾乎都是 .htaccess 中的語法錯誤。檢查 Apache 錯誤日誌:
tail -f /var/log/apache2/error.log
重新導向迴圈
# ❌ 迴圈 — 沒有條件阻止重複匹配
RewriteRule ^(.*)$ https://example.com/ [R=301,L]
# ✅ 加入 HTTPS 條件
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://example.com/ [R=301,L]
查詢字串遺失
# ❌ 查詢字串被丟棄
RewriteRule ^old-page$ /new-page [R=301,L]
# ✅ 使用 QSA 旗標保留
RewriteRule ^old-page$ /new-page [R=301,L,QSA]
除錯
# 啟用重寫日誌(Apache 2.4)
LogLevel alert rewrite:trace3
# 使用 curl 測試
curl -I http://example.com/old-page
curl -IL http://example.com/old-page
或使用 301check.com 視覺化完整的重新導向鏈路。