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

use*_*010 113 nginx nginx-location

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

我尝试了以下内容

server {
  location /first/location/ | /second/location/ {
  ..
  ..
  }
}
Run Code Online (Sandbox Code Playgroud)

但是nginx reload抛出了这个错误:

nginx: [emerg] invalid number of arguments in "location" directive**
Run Code Online (Sandbox Code Playgroud)

cur*_*ips 182

尝试

location ~ ^/(first/location|second/location)/ {
  ...
}
Run Code Online (Sandbox Code Playgroud)

〜表示为url使用正则表达式.^表示从第一个字符检查.这将寻找一个/后面的任一个位置,然后是另一个/.

  • 注意:如果经常发生(如数千),则由于正则表达式匹配而导致性能下降.匹配顺序也大不相同.在很多"小"的情况下,它会表现得像你想要的那样,但这是值得注意的.我个人希望Nginx"位置"支持多个"="条件,而不是依赖于正则表达式规则. (25认同)
  • FWIW,这不适用于`proxy_pass`规则. (7认同)
  • 恕我直言,这应该更有效:location~(patternOne | patternTwo){...} (4认同)
  • 当原始 URL 没有斜杠结尾时,这对我不起作用 (4认同)
  • 这个解决方案对我不起作用;但是@stamster 的评论确实如此;我正在运行`nginx/1.13.2` (2认同)
  • 如果您需要`proxy_pass` 工作,请参阅此答案:/sf/answers/3263795951/ (2认同)

Col*_*ney 76

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

server {
    location /first/location/ {
        include shared.conf;
    }
    location /second/location/ {
        include shared.conf;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个示例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
";
Run Code Online (Sandbox Code Playgroud)

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

Mik*_*ike 31

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

error_page 418 = @common_location;
location /first/location/ {
    return 418;
}
location /second/location/ {
    return 418;
}
location @common_location {
    # The common configuration...
}
Run Code Online (Sandbox Code Playgroud)

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

包含文件的主要优点(据我所知)是,它对于您可以包含的内容更加灵活 - 例如,它不必是完整的位置块.但它也只是主观地比命名位置有点笨拙.

另请注意,您可以在类似情况下使用相关解决方案:嵌套位置.我们的想法是,您将从一个非常一般的位置开始,对几个可能的匹配应用一些公共配置,然后为要匹配的不同类型的路径分别设置嵌套位置.例如,执行以下操作可能很有用:

location /specialpages/ {
    # some config
    location /specialpages/static/ {
        try_files $uri $uri/ =404;
    }
    location /specialpages/dynamic/ {
        proxy_pass http://127.0.0.1;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 最好在返回 418 error_page 上添加一个解释,这有点令人困惑,但基本上这是使用错误页面作为 goto 块,418 错误代码是“这是一个茶壶”笑话,它是少数安全的笑话之一使用的代码 (2认同)

sta*_*ter 12

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

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

所以一个人可以很容易地使用指向相同位置块/规则的简单管道语法的多个模式。

  • 这个答案是/sf/answers/2475869931/的重复,我不知道为什么人们在写自己的答案之前不阅读答案 (2认同)