Перенаправлення Nginx на основі агента користувача


15

Ось моя поточна конфіденційність 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
  }
}

це чудово працює, і те, www.domain.comі www.domain2.comподають однаковий контент.

тепер я хотів би додати

якщо користувач відвідує www.domain.com, а агент користувача - xxx, перенаправляйте на www.domain2.com

Я шукав і перепробував багато методів, але жоден з них не працює.


Ви все ще хочете подавати один і той же вміст, навіть після переадресації?
Поті Калімуту

@Pothi так, саме
wong2

Добре. Будь ласка, перевірте мою відповідь.
Поті Калімуту

Відповіді:


12

Є два способи виправити цю проблему.

  1. Майте два окремих "серверних" блоки для www.domain.com та www.domain2.com та додайте наступні рядки правил до блоку "сервер" www.domain.com. Це рекомендований спосіб вирішення цього питання.

    if ($http_user_agent ~* "^xxx$") {
       rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    
  2. Якщо ви хочете керувати переадресацією за допомогою одного блоку "сервер" для обох доменів, спробуйте нижче правила

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

Пряма цитата з nginx.com/resources/wiki/start/topics/depth/ifisevil ... "Єдині 100% безпечні речі, які можна зробити всередині, якщо в контексті локації є: return and rewrite".
Поті Калімуту

6

Крок 1. Майте два серверних блоки, по одному для domain.com і domain2.com.

Крок 2: Використовуйте, якщо правильно, як це зло, якщо його неправильно використовувати.

Ось повне рішення ...

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

Замість 301 ви також можете використовувати 302, залежно від випадку використання.
Поті Калімутху

хм, я думаю, що це рішення містить занадто багато дублюючих кодів
wong2

Існує кілька способів вирішити проблему. Я розмістив своє рішення лише для того, щоб змусити вас бачити логіку, за якою це можна було б вирішити. Існує кілька способів уникнути дублікатів.
Pothi Kalimuthu

4

Рекомендованим способом, ймовірно, було б використання а mapтакож через те, що ці змінні оцінюються лише тоді, коли вони використовуються.

Також використання return 301 ...переважніше над переписуваннями, оскільки регулярного вираження не потрібно складати.

Ось приклад того, де хост і користувальницький агент як об'єднаний рядок порівнюються з одним регулярним виразом:

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

І це може бути ще більш гнучким, наприклад, якщо в ньому не 2, а більше доменів.

Тут ми відображаємо www.domain.comз користувачем агенти , починаючи з Agentдо http://www.domain2.comі www.domain2.comз точним агентом користувача Other Agentдля 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;
  }
}

Зверніть увагу: для роботи зв'язаного рядка на карті вам знадобиться nginx 0.9.0 або вище.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.