如何在 nginx 中创建一个与 AND 一起使用且不带斜杠的位置?

Rob*_*Rob 63 nginx

现在我有这个配置:

location ~ ^/phpmyadmin/(.*)$
{
        alias /home/phpmyadmin/$1;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我访问www.mysite.com/phpmyadmin(注意缺少尾部斜杠),它不会找到我要查找的 404。我假设是因为我不包含尾部斜杠。我怎样才能解决这个问题?

kbe*_*bec 52

更好的解决方案:

location ~ ^/phpmyadmin(?:/(.*))?$ {
    alias /home/phpmyadmin/$1;
}
Run Code Online (Sandbox Code Playgroud)

确保服务器有权限/home/phpmyadmin首先。


与已接受答案的差异解释:

这都是关于正则表达式

首先,^char 意味着你想从字符串的开头而不是中间的某个地方匹配。将$在匹配于字符串的末尾结束手段。

(?:)意味着非捕获组 - 我们不希望在捕获结果中使用它,但我们希望对一些字符进行简单分组。我们这样分组,因为我们希望/字符是子路径的一个不重要的部分,而不是父路径的重要部分。

  • @Meow 在接受的答案上回答了这个问题 (3认同)
  • 这应该是公认的答案 (2认同)

hay*_*ker 42

它可能在您使用的正则表达式中——

location ~ ^/phpmyadmin/(.*)$
Run Code Online (Sandbox Code Playgroud)

以上将匹配/phpmyadmin/、/phpmyadmin/anything/else/here,但它不会匹配/phpmyadmin,因为正则表达式包含尾部斜杠。

你可能想要这样的东西:

location ~ /phpmyadmin/?(.*)$ {
    alias /home/phpmyadmin/$1;
}
Run Code Online (Sandbox Code Playgroud)

问号是一个正则表达式量词,应该告诉 nginx 匹配前一个字符(斜杠)的零或一个。

警告:社区将此解决方案视为可能的安全风险

  • 模式不太正确。它也可以匹配像“/phpmyadmin1234”这样的路径,显然这不是你想要的。@kbec 的解决方案是正确的。 (19认同)
  • 我很抱歉明确地拒绝了这一点,但@Meow 评论是**重要的**方式,可以忽略。这可能导致配置错误的 Web 服务器,其中可能包含安全漏洞。 (3认同)

wom*_*ble 11

你为什么不直接使用

location /phpmyadmin {
    alias /home/phpmyadmin;
}
Run Code Online (Sandbox Code Playgroud)

?

  • 这样做的问题是它也会匹配 `/phpmyadminblahblahblahblah` 或任何其他组合 (7认同)

dlo*_*zan 7

我知道这是一个老问题,但是对于通过 Google 来到这里的任何人,我都通过以下方式解决了它(@kbec 的变体,非常好):

location ~ ^/foo(/.*)?$ {
  proxy_pass http://$backend$1$is_args$args;
}
Run Code Online (Sandbox Code Playgroud)

这将捕获任何变体/foo并将其重定向到/bar另一个 url(包括参数)。我用proxy_pass指令显示它,但它也适用于alias.

  • /foo -> /bar
  • /foo/ -> /bar/
  • /foo/sub -> /bar/sub
  • /foo/sub1/sub2/?param=value -> /bar/sub1/sub2/?param=value

它有效是因为$1可以选择捕获子资源加上前导斜杠,因此它不会捕获诸如/fooextra/. 它还将正确重定向存在或不存在的结束斜杠。

编辑:检查有关此方法的警告的评论。

  • 感谢您考虑想要使用 proxy_pass 并因此关心参数的极端情况。你有我的赞成票。 (2认同)