it-swarm.com.de

Nginx-Weiterleitung basierend auf dem Benutzeragenten

Hier ist meine aktuelle Nginx-Konf:

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

es funktioniert gut, beide www.domain.com und www.domain2.com dienen den gleichen Inhalt.

jetzt möchte ich hinzufügen

wenn der Benutzer www.domain.com besucht und der Benutzeragent xxx ist, leiten Sie zu www.domain2.com weiter

Ich habe viele Methoden gesucht und ausprobiert, aber keine davon funktioniert.

15
wong2

Es gibt zwei Möglichkeiten, um dieses Problem zu beheben.

  1. Verwenden Sie zwei separate "Server" -Blöcke für www.domain.com und www.domain2.com und fügen Sie die folgenden Regelzeilen zum "Server" -Block www.domain.com hinzu. Dies wird empfohlen, um dieses Problem zu lösen.

    if ($http_user_agent ~* "^xxx$") {
       rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    
  2. Wenn Sie die Umleitung mit einem einzigen "Server" -Block für beide Domänen verwalten möchten, versuchen Sie es mit den folgenden Regeln

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

Schritt 1: Haben Sie zwei Serverblöcke, jeweils einen für domain.com und domain2.com.

Schritt 2: Wenn richtig verwendet da es böse ist, wenn es falsch verwendet wird.

Hier ist die komplette Lösung ...

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
  }
}
6
Pothi Kalimuthu

Der empfohlene Weg wäre wahrscheinlich die Verwendung eines map , auch weil diese Variablen nur ausgewertet werden, wenn sie verwendet werden.

Auch die Verwendung von return 301 ... wird dem Umschreiben vorgezogen, da kein regulärer Ausdruck kompiliert werden muss.

Hier ein Beispiel dafür, wo Host und Benutzeragent als verkettete Zeichenfolge mit einem einzelnen regulären Ausdruck verglichen werden:

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

Und dies könnte noch flexibler sein, zum Beispiel wenn nicht zwei, sondern mehr Domains beteiligt sind.

Hier kartieren wir www.domain.com mit Benutzeragenten beginnend mit Agent bis http://www.domain2.com und www.domain2.com mit dem genauen Benutzeragenten Other Agent bis 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 [~ # ~] Sie benötigen Nginx 0.9.0 oder höher, damit die verkettete Zeichenfolge in der Map funktioniert.

4
Koen.