在一個位置內設置一個包羅萬象的地方,並回退到index.php

在一個位置內設置一個包羅萬象的地方,並回退到index.php

我正在努力處理 nginx 配置。我有一個server區塊,我希望所有請求都轉到index.php?tags=$uri,除非$uri存在(如index.php?a=b/?a=b)。

我期望:

try_files $uri index.php?tags=$uri;

但是,不,那太簡單了。這不適用於/?a=b,顯然沒有找到,所以它指向index.php?tags=/

也許如果我明確包含一個index,這是合理的:

index index.php;

沒有。沒有骰子。全面相同的確切結果。

也沒有$args$request_uri或組合。也不是它:

try_files $request_uri/index.php $request_uri index.php?tags=$request_uri; // now I'm just guessing

阿帕契總是知道我的意思。為什麼nginx沒有?我想要這些重定向(不帶redirectif):

/   => /index.php
/index.php   => /index.php
/index.php?a=b   => /index.php?a=b
/?a=b   => /index.php?a=b
/foo   => /index.php?tags=foo (or /index.php?tags=/foo)
/foo/bar   => /index.php?tags=foo/bar (or /index.php?tags=/foo/bar)
/foo?bar=yes   => /index.php?tags=/foo%3Fbar%3Dyes

我希望在重定向時對查詢字串進行編碼,而不是對路徑進行編碼,但實際上這並不那麼重要。

(我也不明白 $uri 和 $request_uri 之間的實際區別。它們似乎一半時間都在做同樣的事情。但那是另一天的事了。)

非常感謝。

答案1

我透過以下配置片段實現了預期的結果:

location = / {
    index index.php;
}

location / {
    try_files $uri /index.php?tags=$request_uri;
}

try_files嘗試...文件。當您/使用它進行查找時,您會搜尋具有相同名稱的文件,它不會被解釋為「尋找索引文件」。index做那個工作。因此,您需要將這種特殊情況與預設的後備位置分開。

最好的部分是您的最後一個願望:參數甚至不會被編碼,因為它們不需要(只有 URI 的第一個問號是相關的,因為後面的所有內容都是參數)。

注意使用$request_uri(其中包含請求的 URI,帶有參數,但不會對其進行規範化/清理)而不是規範化的$uri(這會清理 URI 並刪除參數)。因此你最終可能會得到:

///foo?bar=yes => index.php?tags=///foo?bar=yes

如果你介意的話,你可以使用$uri結合$args:

location = / {
    index index.php;
}

location / {
    try_files $uri /index.php?tags=$uri?$args;
}

生產:

///foo?bar=yes => index.php?tags=/foo?bar=yes

相關內容