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


46

现在我有这个配置:

location ~ ^/phpmyadmin/(.*)$
{
        alias /home/phpmyadmin/$1;
}

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


2
我知道这个问题已经很老了,不过我想强调一下需要更改已接受的答案。没有经验的用户(将搜索这种QA的用户)可能会使用当前接受的答案来创建安全漏洞。
Bozzy

Answers:


34

您可能正在使用正则表达式-

location ~ ^/phpmyadmin/(.*)$

上面的代码与/ phpmyadmin /,/ phpmyadmin / anything / else / here匹配,但与/ phpmyadmin不匹配,因为正则表达式包含斜杠。

您可能想要这样的东西:

location ~ /phpmyadmin/?(.*)$ {
    alias /home/phpmyadmin/$1;
}

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

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


谢谢!还要感谢您的解释。将来会派上用场。
罗布

15
该模式不太正确。它还可以匹配“ / phpmyadmin1234”之类的路径,显然这不是您想要的。@kbec的解决方案是正确的。
2015年

3
很抱歉,我明确拒绝了这个建议,但是@Meow注释是一种重要的忽略方法。这可能会导致配置错误的Web服务器,其中可能包含安全漏洞。
Daniel F

34

更好的解决方案:

location ~ ^/phpmyadmin(?:/(.*))?$ {
    alias /home/phpmyadmin/$1;
}

确保服务器具有优先权/home/phpmyadmin


与可接受答案的差异说明:

这都是关于正则表达式的

首先,^char表示您要从字符串开头而不是中间位置进行匹配。将$在匹配于字符串的末尾结束手段。

(?:)方法非捕获组-我们不希望它在捕获的结果,但我们要简单一些组字符。我们之所以将其分组,是因为我们希望/char成为子路径的非重要部分,而不是父路径的重要部分。


为什么会更好?
Meekohi

2
@Meow在接受的答案上回答了这个问题
kbec

2
这应该是公认的答案
Yonn Trimoreau

@Meekohi我写了解释
kbec

8

你为什么不只用

location /phpmyadmin {
    alias /home/phpmyadmin;
}


因为那对我不起作用。看到这里:serverfault.com/questions/375602/…–
Rob

1
@Rob是否在alias指令末尾没有斜杠的情况下进行了尝试?
Shane Madden

这实际上是正确的答案和正确的方法。只需排除尾部斜杠即可,它适用于带有或不带有尾部斜杠的网址。无需在Nginx上使任何事情变得复杂,就可以使其简单,复杂的正则表达式和其他有趣的事情只会减慢Nginx的速度。
MitchellK

4
问题在于它也将匹配/phpmyadminblahblahblahblah或其他任意组合
Gary Green

6

我知道这是一个古老的问题,但是对于任何通过Google最终出现在这里的人,我可以通过以下方式解决此问题(@kbec的版本非常不错):

location ~ ^/foo(/.*)?$ {
  proxy_pass http://$backend$1$is_args$args
}

这将捕获任何变体/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/。它还将正确地重定向当前或不存在的结束斜杠。


1
感谢您考虑要使用proxy_pass并因此关心参数的特殊情况。你有我的支持。
Daniel F

2

此重定向将重写带有和不带有尾部斜杠的URL。斜线之后的所有内容都不会被覆盖。

domain.com/location =>重定向到domain.com/new/location
domain.com/location =>重定向到domain.com/new/location
domain.com/location/other =>未重定向

server {
  # 301 URL Redirect
  rewrite ^/location/?$ /new/location permanent;
}


0

我是那样做的

rewrite ^/promo/?$     http://example.com/promo/page43902.html;
location /promo/ {
    root /var/www;
}

0

为什么不简单地进行两次重写:

location ~ ^/phpmyadmin
{
    rewrite /phpmyadmin /home/phpmyadmin/ break;
    rewrite /phpmyadmin/(.*) /home/phpmyadmin/$1 break;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.