사용자 에이전트를 기반으로 한 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으로 리디렉션

검색하고 많은 방법을 시도했지만 그중 아무것도 작동하지 않습니다.


리디렉션 후에도 동일한 콘텐츠를 계속 게재 하시겠습니까?
Pothi Kalimuthu

@Pothi 예, 정확히
wong2

확인. 내 대답을 확인하십시오.
Pothi Kalimuthu

답변:


12

이 문제를 해결하는 데는 두 가지 방법이 있습니다.

  1. www.domain.com 및 www.domain2.com에 대해 별도의 "서버"블록이 두 개 있고 "server"블록 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".
Pothi Kalimuthu

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도 사용할 수 있습니다.
Pothi Kalimuthu

흠, 나는이 솔루션이 너무 많은 중복 코드를 포함하고 있다고 생각한다
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 Agenthttp://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 맵에서 연결된 문자열이 작동하려면 nginx 0.9.0 이상이 필요합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.