Nginx-Weiterleitung basierend auf User Agent


15

Hier ist meine aktuelle 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
  }
}

es funktioniert gut, beide www.domain.comund www.domain2.comdienen den gleichen Inhalt.

Jetzt möchte ich hinzufügen

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

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


Möchten Sie auch nach der Weiterleitung den gleichen Inhalt bereitstellen?
Pothi Kalimuthu

@Pothi ja, genau
wong2

In Ordnung. Bitte überprüfen Sie meine Antwort.
Pothi Kalimuthu

Antworten:


12

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

  1. Haben Sie zwei separate "Server" -Blöcke für www.domain.com und www.domain2.com und fügen Sie die folgenden Zeilen von Regeln zum "Server" -Block www.domain.com hinzu. Dies ist eine empfohlene Lösung für dieses Problem.

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

Direktes Zitat von nginx.com/resources/wiki/start/topics/depth/ifisevil ... "Die einzigen 100% sicheren Dinge, die in einem Standortkontext ausgeführt werden können, sind: return and rewrite".
Pothi Kalimuthu

6

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

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

Hier ist die Komplettlö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
  }
}

Anstelle von 301 können Sie auch 302 verwenden, abhängig von Ihrem Anwendungsfall.
Pothi Kalimuthu

hmm, ich denke, diese Lösung enthält zu viele duplizierende Codes
wong2

Es gibt mehrere Möglichkeiten, ein Problem zu lösen. Ich habe meine Lösung nur veröffentlicht, damit Sie die Logik dahinter erkennen, wie sie gelöst werden kann. Es gibt mehrere Möglichkeiten, um Duplikate zu vermeiden.
Pothi Kalimuthu

4

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

Auch wird die Verwendung von return 301 ...Rewrites vorgezogen, da keine regulären Ausdrücke kompiliert werden müssen.

Hier ein Beispiel, in dem Host und User-Agent als verkettete Zeichenfolge mit einer einzelnen Regex 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, wenn zum Beispiel nicht 2, sondern mehr Domänen beteiligt sind.

Hier bilden wir www.domain.commit User-Agents , beginnend mit Agentbis http://www.domain2.comund www.domain2.commit dem genauen User-Agent Other Agentan 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;
  }
}

Hinweis: Sie benötigen Nginx 0.9.0 oder höher, damit die verkettete Zeichenfolge in der Karte funktioniert.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.