Reindirizzamento di Nginx basato sull'agente utente


15

Ecco la mia attuale conf di nginx:

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

funziona bene, entrambi www.domain.come www.domain2.comoffrono lo stesso contenuto.

ora vorrei aggiungere

se l'utente visita www.domain.com e l'agente utente è xxx, reindirizza a www.domain2.com

Ho cercato e provato molti metodi, ma nessuno di questi funziona.


Vuoi comunque offrire lo stesso contenuto, anche dopo il reindirizzamento?
Pothi Kalimuthu,

@Pothi sì, esattamente
wong2,

Ok. Per favore, controlla la mia risposta.
Pothi Kalimuthu,

Risposte:


12

Esistono due modi per risolvere questo problema.

  1. Disponi di due blocchi "server" separati per www.domain.com e www.domain2.com e aggiungi le seguenti righe di regole al blocco "server" www.domain.com. Questo è un modo consigliato per risolvere questo problema.

    if ($http_user_agent ~* "^xxx$") {
       rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    
  2. Se desideri gestire il reindirizzamento con un singolo blocco "server" per entrambi i domini, prova le regole seguenti

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

Citazione diretta da nginx.com/resources/wiki/start/topics/depth/ifisevil ... "Le uniche cose sicure al 100% che possono essere fatte all'interno se in un contesto di posizione sono: ritorno e riscrittura".
Pothi Kalimuthu,

6

Passaggio 1: disporre di due blocchi server, uno ciascuno per domain.com e domain2.com.

Passaggio 2: utilizzare se correttamente in quanto è male se utilizzato in modo errato.

Ecco la soluzione 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
  }
}

Invece di 301, puoi usare anche 302, a seconda del tuo caso d'uso.
Pothi Kalimuthu,

hmm, penso che questa soluzione contenga troppi codici di duplicazione
wong2,

Esistono diversi modi per risolvere un problema. Ho pubblicato la mia soluzione solo per farti vedere la logica dietro come potrebbe essere risolto. Esistono diversi modi per evitare duplicati.
Pothi Kalimuthu,

4

Il modo consigliato sarebbe probabilmente usare a map, anche perché queste variabili vengono valutate solo quando vengono utilizzate.

Anche l'uso di return 301 ...è preferito rispetto alle riscritture, perché non è necessario compilare alcuna espressione regolare.

Ecco un esempio di dove host e user-agent come stringa concatenata vengono confrontati con una singola 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 questo potrebbe essere ancora più flessibile, ad esempio se non ci fossero 2 ma più domini coinvolti.

Qui mappiamo www.domain.comcon user-agent a partire Agentda http://www.domain2.come www.domain2.comcon l'esatto user-agent Other Agenta 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 è necessario nginx 0.9.0 o versione successiva affinché la stringa concatenata nella mappa funzioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.