Redirecionamento Nginx com base no agente do usuário

8

Aqui está meu conf nginx atual:

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
  }
}

funciona bem, tanto www.domain.com como www.domain2.com têm o mesmo conteúdo.

agora gostaria de adicionar

if the user is visiting www.domain.com and the user agent is xxx then redirect to www.domain2.com

Eu pesquisei e experimentei muito método, mas nenhum deles funciona.

    
por wong2 08.05.2016 / 08:46

3 respostas

6

Existem duas formas de corrigir este problema.

  1. Tenha dois blocos "server" separados para www.domain.com & www.domain2.com e adicione as seguintes linhas de regras ao bloco "servidor" www.domain.com. Essa é uma maneira recomendada de resolver esse problema.

    if ($http_user_agent ~* "^xxx$") {
       rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    
  2. Se você quiser gerenciar o redirecionamento com um único bloco "servidor" para os dois domínios, tente as regras abaixo

    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;
    }
    
por 08.05.2016 / 09:17
3

Etapa 1: tenha dois blocos de servidor, um para cada domínio.com e domínio2.com.

Passo 2: Use se corretamente , pois é mal usado incorretamente.

Aqui está a solução completa ...

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
  }
}
    
por 08.05.2016 / 13:47
1

A forma recomendada provavelmente seria usar um map , também porque essas variáveis são avaliadas apenas quando eles são usados.

Além disso, o uso de return 301 ... é preferível às reescritas, porque nenhuma expressão regular precisa ser compilada.

Aqui, um exemplo de onde host e user-agent como uma string concatenada são comparados a um único regex:

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;
  }
}

E isso pode ser ainda mais flexível, por exemplo, se não houver 2, mas mais domínios envolvidos.

Aqui, mapeamos www.domain.com com user agents começando com Agent to http://www.domain2.com e www.domain2.com com o user agent Other Agent to 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;
  }
}

NB você precisará do nginx 0.9.0 ou superior para que a string concatenada no mapa funcione.

    
por 12.01.2017 / 00:51

Tags