基于用户代理的Nginx重定向


15

这是我当前的nginx conf:

server {
  listen 90;
  server_name www.domain.com www.domain2.com;
  root /root/app;
  location / {
    try_files $uri =404;
  }
  location ~ /([-\w]+)/(\w+)/ {
    proxy_pass bla bla
  }
}

它工作正常,两者www.domain.comwww.domain2.com提供相同的内容。

现在我想添加

如果用户正在访问www.domain.com并且用户代理是xxx,则重定向到www.domain2.com

我已经搜索并尝试了很多方法,但是它们都不起作用。


即使重定向后,您是否仍要提供相同的内容?
Pothi Kalimuthu

@Pothi是的,完全是
wong2 '16

好。请检查我的答案。
Pothi Kalimuthu

Answers:


12

有两种方法可以解决此问题。

  1. 对www.domain.com和www.domain2.com有两个单独的“服务器”块,并将以下几行规则添加到“服务器”块www.domain.com。这是解决此问题的推荐方法。

    if ($http_user_agent ~* "^xxx$") {
       rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    
  2. 如果您要通过两个域的单个“服务器”块来管理重定向,请尝试以下规则

    set $check 0;
    if ($http_user_agent ~* "^xxx$") {
        set $check 1;
    }
    if ($host ~* ^www.domain.com$) {
        set $check "${check}1";
    }
    if ($check = 11) {
        rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    

直接引自nginx.com/resources/wiki/start/topics/depth/ifisevil ...“如果在位置上下文中,可以在内部完成的唯一100%安全的事情是:返回并重写”。
Pothi Kalimuthu

6

步骤1:拥有两个服务器块,每个服务器块分别用于domain.com和domain2.com。

步骤2:如果使用正确,则使用正确,否则使用将有害。

这是完整的解决方案...

server {
  listen 90;
  server_name www.domain.com;
  root /root/app;

  # redirect if 'xxx' is found on the user-agent string
  if ( $http_user_agent ~ 'xxx' ) {
    return 301 http://www.domain2.com$request_uri;
  }

  location / {
    try_files $uri =404;
  }
  location ~ /([-\w]+)/(\w+)/ {
    proxy_pass bla bla
  }
}

server {
  listen 90;
  server_name www.domain2.com;
  root /root/app;
  location / {
    try_files $uri =404;
  }
  location ~ /([-\w]+)/(\w+)/ {
    proxy_pass bla bla
  }
}

根据您的用例,您也可以使用302而不是301。
Pothi Kalimuthu

嗯,我认为此解决方案包含过多的重复代码
wong2 2013年

有多种解决问题的方法。我发布解决方案只是为了让您了解如何解决该问题的逻辑。有多种避免重复的方法。
Pothi Kalimuthu'5

4

推荐的方法可能是使用map,也因为这些变量仅在使用时才求值。

而且,return 301 ...重写优于使用,因为不必编译正则表达式。

这是将host和user-agent作为连接字符串与单个正则表达式进行比较的示例:

map "$host:$http_user_agent" $my_domain_map_host {
  default                      0;
  "~*^www.domain.com:Agent.*$" 1;
}

server {
  if ($my_domain_map_host) {
    return 302 http://www.domain2.com$request_uri;
  }
}

而且这可能更加灵活,例如,如果不涉及2个但涉及更多的域。

在这里,我们映射了www.domain.com以开头的用户代理Agenthttp://www.domain2.comwww.domain2.com以到的确切用户代理Other Agent进行映射http://www.domain3.com

map "$host:$http_user_agent" $my_domain_map_host {
  default                             0;
  "~*^www.domain.com:Agent.*$"        http://www.domain2.com;
  "~*^www.domain2.com:Other Agent$"   http://www.domain3.com;
}

server {
  if ($my_domain_map_host) {
    return 302 $my_domain_map_host$request_uri;
  }
}

注意,您需要nginx 0.9.0或更高版本才能使map中的串联字符串起作用。

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.