
虛擬主機、轉址與網址重寫的設定
虛擬主機的基本結構
Nginx
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name example.com;
root /var/www/example/public;
index index.php index.html;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
注意:較新版本的 Nginx 已改用獨立的 http2 on; 指令,舊寫法是在 listen 後面加 http2 參數。
Apache
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/example/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
<Directory /var/www/example/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.error.log
CustomLog ${APACHE_LOG_DIR}/example.access.log combined
</VirtualHost>
http 轉 https
Nginx
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
用 return 而不是 rewrite——效率較好,語意也更清楚。
Apache
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
或用 mod_rewrite:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
統一 www 與非 www
加上協定,同一頁面可能有四種網址形式,必須擇一為主。
Nginx:獨立的 server 區塊處理
server {
listen 443 ssl;
server_name www.example.com;
# 憑證需涵蓋 www
return 301 https://example.com$request_uri;
}
轉址用的 server 區塊也需要憑證,否則使用者在轉址前就會看到憑證警告。
Apache
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]
正規化的完整說明見網址正規化與重複內容怎麼處理。
轉址的四個常見錯誤
一、用 302 而非 301
永久搬遷應該用 301。302 表示暫時,搜尋引擎不會完整傳遞評價。
二、產生轉址鏈
例如 http://www → https://www → https://(無 www),經過兩次跳轉。
應該一次到位:http://www 直接轉到 https://(無 www)。
三、轉址迴圈
最常見於反向代理或 CDN 環境——前端已經是 https,但回源時是 http,後端又判斷要轉 https,形成循環。
解法:判斷 X-Forwarded-Proto 而非直接判斷 HTTPS:
# Apache 於代理環境下
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
四、全部轉到首頁
舊網址大量轉向首頁,會被視為軟性 404。應盡量對應到相近的頁面。
舊網址對應的批次轉址
改版時常需要大量的一對一對應。
Nginx:使用 map
map $request_uri $redirect_target {
default "";
/old-page.html /new-page;
/products/123.php /products/abc;
}
server {
if ($redirect_target != "") {
return 301 $redirect_target;
}
}
map 比大量的 if 或 location 效率高得多,數千筆對應也不成問題。
Apache:使用 RewriteMap 或 Redirect
Redirect 301 /old-page.html /new-page
數量龐大時建議使用 RewriteMap 搭配外部檔案。
改版轉址的完整規劃見網站改版或更換網域,SEO 排名怎麼保住。
try_files 與 rewrite 的選擇
Nginx 中處理前端控制器(單一入口)時,優先使用 try_files:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
它會依序嘗試實體檔案、目錄,最後才交給 index.php。比用 rewrite 判斷檔案是否存在更直接,也避免了 if 的常見陷阱。
Nginx 的 if 在 location 內的行為有已知的限制,官方文件也建議盡量避免——能用 try_files 或 map 解決的就不要用 if。
本文的設定範例以常見的環境為例,實際的路徑、模組名稱與指令可能因作業系統、版本與安裝方式而異。套用前請先在測試環境驗證,並確實備份原設定檔。