Nginx - 基于查询字符串参数重定向

Kev*_*vin 6 nginx

我们的 nginx 配置中有一些复杂的问题需要解决。目前我们在文档根目录中安装了一个软件。该软件使用单个入口点(index.php)和查询字符串来显示内容。示例 URL 为:

/index.php?forums/forum-name.1
/index.php?threads/thread-name.1
/index.php?users/user-name.1
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

所以基本上,我需要重定向index.php请求的某个子集(仅包含?forums,?threads,?users等...),然后删除index.php部分并发送到/f/目录。

我整个上午都在玩这个,但就是无法让它按照我需要的方式工作。

Ric*_*ith 5

要管理复杂的重定向,特别是在涉及查询字符串时,map可以使用该指令。

您无法匹配和表达式中的查询字符串(此后的任何内容?),因为它不是规范化 URI 的一部分,但是,包含带有查询字符串的原始请求。locationrewrite$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;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

始终在块正则表达式中使用命名捕获map。映射表达式在return语句中进行计算。据我了解,每次遇到包含正则表达式的nginx语句(例如,某些块和某些语句)时,数字捕获都会重置。使用命名捕获可确保它们保留在语句的范围内。rewritelocationifreturn

请参阅有关使用的注意事项if

  • 查询字符串值在变量“$args”中可用(对于完整字符串),“$arg_name”对于按名称的单个参数,“$is_args”(如果存在查询字符串则为“?”,如果没有则为空)。您可以在位置块中评估这些并将它们添加到 return、rewrite、proxy_pass 等指令中 (3认同)