我們的 nginx 設定中有一些複雜的問題需要解決。目前我們在文檔根目錄中安裝了一個軟體。該軟體使用單一入口點(index.php)和查詢字串來顯示內容。範例 URL 為:
/index.php?forums/forum-name.1
/index.php?threads/thread-name.1
/index.php?users/user-name.1
ETC...
現在,我們將該軟體移至文檔根目錄的子目錄中/f/
,並將一個新軟體安裝到文檔根目錄中。該軟體也使用index.php(不過沒有查詢字串)。因此,我們需要製定一組重寫規則,僅重寫舊軟體中的 URL。同時,我們也將從 URL 中刪除 index.php。一組範例映射是:
/index.php?forums/forum-name.1 --> /f/forums/forum-name.1
/index.php?threads/thread-name.1 --> /f/threads/thread-name.1
/index.php?users/user-name.1 --> /f/users/user-name.1
所以基本上,我需要重定向index.php請求的某個子集(僅包含?forums,?threads,?users等...),然後刪除index.php部分並發送到/f/目錄。
我整個上午都在玩這個,但就是無法讓它按照我需要的方式工作。
答案1
要管理複雜的重定向,特別是在涉及查詢字串時,map
可以使用該指令。
您無法匹配和表達式中的查詢字串(此後的任何內容?
),因為它不是規範化 URI 的一部分,但是,包含帶有查詢字串的原始請求。location
rewrite
$request_uri
$request_uri
如果參數沒有以一致的順序發送,則匹配可能會出現問題,並且包含奇怪字元的 URI 也會進行百分比編碼。
該map
指令可以匹配字串和/或正規表示式。看這個文件了解詳情。
例如:
map $request_uri $redirect {
default 0;
~*^/index\.php\?(?<suffix>(forums|threads|users).*)$ /f/$suffix;
...
}
server {
...
if ($redirect) {
return 301 $redirect;
}
...
}
總是使用命名捕獲在map
區塊正規表示式中。映射表達式在return
語句中進行計算。據我了解,每次nginx
遇到包含正規表示式(例如rewrite
,一些location
區塊和一些if
語句),數字捕獲被重置。使用命名捕獲確保它們仍在return
聲明的範圍內。
看這個警告關於使用if
.