ユーザーエージェントに基づくNginxリダイレクト


15

ここに私の現在の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
  }
}

それが正常に動作します、両方のwww.domain.comwww.domain2.com同じコンテンツを提供します。

今、私は追加したいと思います

ユーザーがwww.domain.comにアクセスしており、ユーザーエージェントがxxxの場合、www.domain2.comにリダイレクトします

私は多くの方法を検索して試しましたが、どれも機能しません。


リダイレクト後も同じコンテンツを提供しますか?
ポティカリムトゥ16年

@Pothiはい、正確に
-wong2

OK。私の答えを確認してください。
ポティカリムトゥ16年

回答:


12

この問題を修正するには2つの方法があります。

  1. www.domain.comとwww.domain2.comの2つの独立した「サーバー」ブロックを用意し、「サーバー」ブロック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およびrewrite」です。
ポティカリムトゥ

6

ステップ1:domain.comおよびdomain2.comにそれぞれ1つずつ、2つのサーバーブロックを用意します。

ステップ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も使用できます。
ポティカリムトゥ16年

うーん、このソリューションには重複コードが多すぎると思う
-wong2

問題を解決する方法は複数あります。ソリューションを投稿したのは、解決方法の背後にあるロジックを確認できるようにするためだけです。重複を避ける方法は複数あります。
ポティカリムトゥ

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.comAgentto http://www.domain2.comで始まるuser-agent www.domain2.comと、正確なuser-agent Other Agenttoでマッピングします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;
  }
}

注意: mapで連結された文字列を機能させるには、nginx 0.9.0以上が必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.