nginx重新規則介紹(二)
示例 - 標準化域名
NGINX重寫規則的最常見用途之一是捕獲網站域名的棄用或非標準版本,並將其重定向到當前名稱。有幾個相關的用例。
從前名稱重定向到當前名稱
此示例NGINX重寫規則將來自www.old-name.com和old-name.com的請求永久重定向到www.new-name.com,使用兩個NGINX變數從原始請求URL捕獲值 - $ scheme是原始協議(http或https)和$ request_uri是完整的URI(在域名後面),包括引數:
server { listen 80; listen 443 ssl; server_name www.old-name.com old-name.com; return 301 $scheme://www.new-name.com$request_uri; }
因為$ request_uri捕獲了域名後面的URL部分,所以如果舊站點和新站點之間存在一對一的頁面對應,則此重寫是合適的(例如,www.new-name.com / about與www.old-name.com/about相同的基本內容。如果您在更改域名之後重新組織了站點,則通過省略$ request_uri將所有請求重定向到主頁可能更安全:
server { listen 80; listen 443 ssl; server_name www.old-name.com old-name.com; return 301 $scheme://www.new-name.com; }
其他一些關於在NGINX中重寫URL的部落格對這些用例使用了重寫指令,如下所示:
# NOT RECOMMENDED
rewrite ^ $scheme://www.new-name.com$request_uri permanent;
這比等效的返回指令效率低,因為它需要NGINX來處理正則表示式,儘管是一個簡單的表示式(插入符號[^],它匹配完整的原始URL)。對於人類讀者來說,相應的返回指令也更容易解釋:返回301更清楚地表明NGINX返回程式碼301而不是重寫...永久符號
新增和刪除www字首
這些示例新增和刪除www字首:
# add 'www' server { listen 80; listen 443 ssl; server_name domain.com; return 301 $scheme://www.domain.com$request_uri; } # remove 'www' server { listen 80; listen 443 ssl; server_name www.domain.com; return 301 $scheme://domain.com$request_uri; }
同樣,返回優於隨後的等效重寫。重寫需要解釋正則表示式 - ^(。*)$ - 並建立一個實際上等同於內建$ request_uri變數的自定義變數($ 1)。
# NOT RECOMMENDED
rewrite ^(.*)$ $scheme://www.domain.com$1 permanent;
將所有流量重定向到正確的域名
這是一個特殊情況,當請求URL與任何伺服器和位置塊不匹配時,可能會因為域名拼寫錯誤而將傳入流量重定向到網站的主頁。它的工作原理是將default_server引數與listen指令和下劃線組合作為server_name指令的引數。
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _;
return 301 $scheme://www.domain.com;
}
我們使用下劃線作為server_name的引數,以避免無意中匹配真實域名 - 可以安全地假設沒有站點將下劃線作為其域名。但是,與配置中的任何其他伺服器塊不匹配的請求最終會在此處顯示,並且要監聽的default_server引數告訴NGINX將此塊用於它們。通過從重寫的URL中省略$ request_uri變數,我們將所有請求重定向到主頁,這是一個好主意,因為具有錯誤域名的請求特別可能使用網站上不存在的URI。
示例 - 強制所有請求使用SSL / TLS
此伺服器阻止所有訪問者使用與您站點的安全(SSL / TLS)連線。
server {
listen 80;
server_name www.domain.com;
return 301 https://www.domain.com$request_uri;
}
其他一些關於NGINX重寫規則的部落格使用if測試和這個用例的重寫指令,如下所示:
# NOT RECOMMENDED
if ($scheme != "https") {
rewrite ^ https://www.mydomain.com$uri permanent;
}
但是這種方法需要額外的處理,因為NGINX必須同時評估if條件並處理rewrite指令中的正則表示式。
示例 - 為WordPress網站啟用漂亮的永久連結
NGINX和NGINX Plus是使用WordPress的網站非常流行的應用程式交付平臺。以下try_files指令告訴NGINX檢查是否存在檔案$ uri,然後檢查目錄$ uri /。如果檔案或目錄都不存在,NGINX會返回一個重定向到/index.php並傳遞查詢字串引數,這些引數由$ args引數捕獲。
location / {
try_files $uri $uri/ /index.php?$args;
}
示例 - 刪除不支援的副檔名的請求
由於各種原因,您的站點可能會收到以與您未執行的應用程式伺服器對應的副檔名結尾的請求URL。在Engine Yard部落格的這個示例中,應用程式伺服器是Ruby on Rails,因此其他應用程式伺服器(Active Server Pages,PHP,CGI等)處理的檔案型別的請求無法提供服務,因此需要拒絕。在將動態生成的資產的任何請求傳遞給應用程式的伺服器塊中,此位置指令在它們到達Rails佇列之前刪除對非Rails檔案型別的請求。
location ~ .(aspx|php|jsp|cgi)$ {
return 410;
}
嚴格地說,響應程式碼410(Gone)旨在用於所請求的資源過去在該URL處可用但不再存在的情況,並且伺服器不知道其當前位置(如果有的話)。它優於響應程式碼404的優點在於它明確指示資源永久不可用,因此客戶端不會再次傳送請求。
您可能希望通過返回響應程式碼403(禁止)和諸如“伺服器僅處理Ruby請求”之類的解釋作為文字字串,為客戶端提供更準確的失敗原因指示。作為替代方案,deny all指令返回403而沒有解釋:
location ~ .(aspx|php|jsp|cgi)$ {
deny all;
}
程式碼403隱式確認所請求的資源存在,因此如果您希望通過向客戶端提供儘可能少的資訊來實現“通過默默無聞的安全性”,則程式碼404可能是更好的選擇。缺點是客戶端可能會反覆重試請求,因為404不會指示故障是暫時還是永久。
示例 - 配置自定義重新路由
在MODXCloud的這個示例中,您有一個資源,可用作一組URL的控制器。您的使用者可以使用更易讀的資源名稱,並重寫(而不是重定向)它將由listing.html的控制器處理。
rewrite ^/listings/(.*)$ /listing.html?listing=$1 last;
例如,使用者友好的URL http://mysite.com/listings/123被重寫為由listing.html控制器http://mysite.com/listing.html?listing=123處理的URL。