我们在 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
。