Redirecionamento Nginx com base no agente do usuário


15

Aqui está o meu atual 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
  }
}

funciona bem, ambos www.domain.come www.domain2.comveicula o mesmo conteúdo.

agora eu gostaria de adicionar

se o usuário estiver visitando www.domain.com e o agente do usuário for xxx, redirecione para www.domain2.com

Eu pesquisei e tentei muitos métodos, mas nenhum deles funciona.


Você ainda deseja veicular o mesmo conteúdo, mesmo após o redirecionamento?
— Pothi Kalimuthu

@Pothi sim, exatamente
— wong2

Está bem. Por favor, verifique minha resposta.
— Pothi Kalimuthu

Respostas:


12

Existem duas maneiras de corrigir esse problema.

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

    if ($http_user_agent ~* "^xxx$") {
       rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    
  2. Se você deseja 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;
    }
    

Citação direta de nginx.com/resources/wiki/start/topics/depth/ifisevil ... "As únicas coisas 100% seguras que podem ser feitas dentro de um ambiente de localização são: retornar e reescrever".
— Pothi Kalimuthu

6

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

Etapa 2: use se corretamente , pois é mau se 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
  }
}

Em vez de 301, você também pode usar 302, dependendo do seu caso de uso.
— Pothi Kalimuthu

hmm, penso que esta solução contém muitos códigos de duplicação
— wong2

Existem várias maneiras de resolver um problema. Postei minha solução apenas para fazer você ver a lógica por trás de como ela poderia ser resolvida. Existem várias maneiras de evitar duplicatas.
— Pothi Kalimuthu

4

A maneira recomendada provavelmente seria usar a map, também porque essas variáveis ​​são avaliadas apenas quando são usadas.

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

Aqui um exemplo de onde host e user-agent como uma cadeia concatenada são comparados a uma única 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 nós mapear www.domain.comcom user-agents começando com Agenta http://www.domain2.come www.domain2.comcom a exata user-agent Other Agentpara 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;
  }
}

Nota: você precisará do nginx 0.9.0 ou superior para que a sequência concatenada no mapa funcione.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.