【问题标题】:nginx.conf redirect multiple conditionsnginx.conf 重定向多个条件
【发布时间】:2011-06-17 12:32:02
【问题描述】:

我想使用 nginx 在两个条件下重定向请求。

这不起作用:

  if ($host = 'domain.com' || $host = 'domain2.com'){
    rewrite ^/(.*)$ http://www.domain.com/$1 permanent;
  }   

这样做的正确方法是什么?

【问题讨论】:

  • 许多人批评使用“if”块而不是单独的服务器块,但在添加单独的服务器块会增加很多复杂性的情况下,这是一个完全可以接受的解决方案。例如。对于 https,您可以避免再次指定所有 SSL 配置。

标签: redirect nginx


【解决方案1】:

我之前也遇到过同样的问题。因为 nginx 不能做复杂的条件或者嵌套的 if 语句,所以你需要计算超过 2 个不同的表达式。

将变量设置为某个二进制值,然后在两个不同的 if 语句中任一条件为真时启用:

set $my_var 0;
if ($host = 'domain.com') {
  set $my_var 1;
}
if ($host = 'domain2.com') {
  set $my_var 1;
}
if ($my_var = 1) {
  rewrite ^/(.*)$ http://www.domain.com/$1 permanent;
}   

【讨论】:

  • 我猜这个答案与新版本的 nginx 有关。我已经尝试了几个小时来让重写规则起作用,但我不得不采用这种方法。虽然它看起来很乱,但它工作得很好。谢谢:)
  • @Jaap 大多数 nginx IF 问题是因为在 LOCATION 内部使用 IF,大多数情况下,服务器级别的 IF 都很好......它们仍然应该避免并用位置、geoip 和地图替换可能的话,但有些情况是你无法避免的
【解决方案2】:

正确的方法是使用专用服务器进行重定向:

server {
  server_name domain.com domain2.com;
  rewrite ^ http://www.domain.com$request_uri? permanent;
}

【讨论】:

  • 感谢您的回复。这会导致 nginx 无法重新/启动。
  • 您收到的错误信息是什么?我发布的内容不会与 if 放在同一个地方,因为 if 已经在服务器中。它将是您已经拥有的服务器块的兄弟。
  • @mark 这是一个新服务器,你必须从现有配置中删除 domain.com 和 domain2.com,以避免重复的 server_names
  • 我投了赞成票,因为它对一台服务器有效。但是,在另一个多租户 nginx 服务器上,它没有。奇数
【解决方案3】:

另一种可能性是

server_name domain.com domain2.com;
set $wanted_domain_name domain.com;
if ($http_host != $wanted_domain_name) {
    rewrite  ^(.*)$  https://$wanted_domain_name$1;
}

所以它会将所有重定向到一个特定的,但它基于我猜的用例

【讨论】:

  • 这实际上不是推荐的方法,因为if () 检查现在发生在每个请求上。最好设置两个服务器块,其中一个(用于不需要的域)只进行重定向。
  • @BenXO 谢谢,我知道。仍然有可能:) 因为还有很多其他的。
【解决方案4】:

这是一种声明式方法:

server {
    listen       80;
    server_name  domain.com domain2.com;
    return 301 $scheme://www.domain.com$uri;    
}

server {
    listen       80  default_server;
    server_name  _;
    #....
}

【讨论】:

  • 这看起来像一个循环
  • 对 domain.com 或 domain2.com 的请求仅与第一个服务器节匹配。请注意,这是完全匹配的;不是通配符。在第二个服务器节中匹配任何其他内容。这就是使它具有声明性的原因。
  • @Unicornist:这不是一个循环,因为它是从domain.comdomain2.com 重定向到www.domain.comwww 主机与第一个服务器块不匹配。
【解决方案5】:

将多个域重写为单个域并避免浏览器中的循环条件。

server {
    listen       80;
    server_name  www.wanted_domain.com wanted_domain.com www.un_wanted_domain.com un_wanted_domain.com;
    if ($host = 'un_wanted_domain.com'){
       return 301 $scheme://www.wanted_domain.com$request_uri;
    }
    if ($host = 'www.un_wanted_domain.com'){
       return 301 $scheme://www.wanted_domain.com$request_uri;
    }

【讨论】:

  • 应该避免这种情况,不需要使用 IF,其中 2 个(或更多)不同的服务器,一个普通服务器和另一个用于重定向的服务器更快更干净
【解决方案6】:

我认为最简单的方法就是使用正则表达式:

if ($host ~ "domain.com|domain2.com") {
    rewrite ^/(.*)$ http://www.example.com/$1 permanent;
}

但只有当你只有字符串时才好;对于复杂的逻辑,肯定是不正确的。

【讨论】:

    猜你喜欢
    • 2017-05-11
    • 2021-02-25
    • 2016-02-12
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多