![在位置内设置一个 catch-all,并回退到 index.php](https://linux22.com/image/1395484/%E5%9C%A8%E4%BD%8D%E7%BD%AE%E5%86%85%E8%AE%BE%E7%BD%AE%E4%B8%80%E4%B8%AA%20catch-all%EF%BC%8C%E5%B9%B6%E5%9B%9E%E9%80%80%E5%88%B0%20index.php.png)
我正在努力解决 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
Apache 总是能理解我的意思。为什么 nginx 不知道呢?我想要这些重定向(不带redirect
或if
):
/ => /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
location = / {
index index.php;
}
location / {
try_files $uri /index.php?tags=$uri?$args;
}
生产:
///foo?bar=yes => index.php?tags=/foo?bar=yes