如何在NGINX配置中对两个位置使用相同的规则?


153

如何在NGINX配置中对两个位置使用相同的规则?

我尝试了以下

server {
  location /first/location/ | /second/location/ {
  ..
  ..
  }
}

但是Nginx重新加载引发了以下错误:

nginx: [emerg] invalid number of arguments in "location" directive**

Answers:


238

尝试

location ~ ^/(first/location|second/location)/ {
  ...
}

~方法使用正则表达式的URL。^从第一个字符开始检查的方法。这将寻找一个/位置,然后是另一个位置,然后是另一个位置/


37
注意:如果这种情况经常发生(例如成千上万次),则由于正则表达式匹配会导致性能下降。匹配的顺序也大不相同。在许多“小”情况下,它的行为会像您想要的那样,但这是需要注意的事情。我个人希望Nginx的“位置”支持多个“ =”条件,而不是依赖于正则表达式规则。
伯纳德

7
恕我直言,这应该更有效:location〜(patternOne | patternTwo){...}
stamster

2
该解决方案对我不起作用;但是@stamster的评论确实做到了;我在跑步nginx/1.13.2
TJ Biddle

1
如果您需要proxy_pass工作,请参见以下答案:stackoverflow.com/a/46625656/1246870
avs099

1
当原始网址不加斜杠结束时,这对我不起作用
The Godfather

88

另一种选择是使用包含的文件在两个前缀位置重复规则。由于前缀位置在配置中与位置无关,因此在以后添加其他正则表达式位置时,使用前缀位置可以避免一些混乱。尽量避免使用正则表达式,这将有助于您的配置顺利扩展。

server {
    location /first/location/ {
        include shared.conf;
    }
    location /second/location/ {
        include shared.conf;
    }
}

这是一个示例shared.conf:

default_type text/plain;
return 200 "http_user_agent:    $http_user_agent
remote_addr:    $remote_addr
remote_port:    $remote_port
scheme:     $scheme
nginx_version:  $nginx_version
";

您可以添加shared.conf示例和位置吗?
ДмитрийКулешов

5
我添加了一个示例shared.conf文件。您可以使用shared.conf的绝对路径,也可以将其放在您的nginx目录中。在这种情况下,它仅包含几个指令。
Cole Tierney

40

正则表达式和包含文件都是好的方法,我经常使用它们。但是另一种选择是使用“命名位置”,这在许多情况下都是有用的方法,尤其是在更复杂的情况下。该官方“如果是邪恶的”页面显示实质上包含以下一种好方法做的事情:

error_page 418 = @common_location;
location /first/location/ {
    return 418;
}
location /second/location/ {
    return 418;
}
location @common_location {
    # The common configuration...
}

这些各种方法都有优点和缺点。正则表达式的一大优点是,您可以捕获部分匹配项并使用它们来修改响应。当然,通常可以通过在原始块中设置变量或使用来使用其他方法获得相似的结果map。正则表达式方法的缺点是,如果您想匹配各种位置,它可能会变得笨拙,再加上正则表达式低优先级可能不适合您想要匹配位置的方式-更不用说显然会对性能产生影响在某些情况下来自正则表达式。

包括文件的主要优点(据我所知)是,它可以精确地包含您要包含的内容,例如,它不必是完整的位置块。但这在主观上也比命名位置要笨拙一些。

还要注意,在类似情况下,您可能可以使用一个相关的解决方案:嵌套位置。这个想法是,您将从一个非常通用的位置开始,对一些可能的匹配项应用一些通用的配置,然后针对要匹配的不同类型的路径分别设置一个嵌套的位置。例如,执行以下操作可能会很有用:

location /specialpages/ {
    # some config
    location /specialpages/static/ {
        try_files $uri $uri/ =404;
    }
    location /specialpages/dynamic/ {
        proxy_pass http://127.0.0.1;
    }
}

7

这是一种简短但有效且经过验证的方法:

location ~ (patternOne|patternTwo){ #rules etc. }

因此,可以使用简单的管道语法轻松地将多个模式指向相同的位置块/规则。

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.