Nginx chuyển hướng dựa trên tác nhân người dùng


15

Đây là nginx conf hiện tại của tôi:

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

nó hoạt động tốt, cả hai www.domain.comwww.domain2.comphục vụ cùng một nội dung.

bây giờ tôi muốn thêm

nếu người dùng đang truy cập www.domain.com và tác nhân người dùng là xxx thì hãy chuyển hướng đến www.domain2.com

Tôi đã tìm kiếm và thử rất nhiều phương pháp nhưng không có phương pháp nào hiệu quả.


Bạn vẫn muốn phục vụ cùng một nội dung, ngay cả sau khi chuyển hướng?
Pothi Kalimuthu

@Pothi có, chính xác
wong2

Đồng ý. Vui lòng kiểm tra câu trả lời của tôi.
Pothi Kalimuthu

Câu trả lời:


12

Có hai cách để khắc phục vấn đề này.

  1. Có hai khối "máy chủ" riêng biệt cho www.domain.com & www.domain2.com và thêm các dòng quy tắc sau vào "máy chủ" chặn www.domain.com. Đây là cách được đề nghị để giải quyết vấn đề này.

    if ($http_user_agent ~* "^xxx$") {
       rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    
  2. Nếu bạn muốn quản lý chuyển hướng bằng một khối "máy chủ" duy nhất cho cả hai miền, hãy thử các quy tắc dưới đây

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

Trích dẫn trực tiếp từ nginx.com/resource/wiki/start/topics/depth/ifisevil ... "Những điều an toàn 100% duy nhất có thể được thực hiện bên trong nếu trong bối cảnh vị trí là: trả lại và viết lại".
Pothi Kalimuthu

6

Bước 1: Có hai khối máy chủ, mỗi khối cho domain.com và domain2.com.

Bước 2: Sử dụng nếu đúng vì nó xấu nếu sử dụng không đúng cách.

Đây là giải pháp hoàn chỉnh ...

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

Thay vì 301, bạn cũng có thể sử dụng 302, tùy thuộc vào trường hợp sử dụng của bạn.
Pothi Kalimuthu

hmm, tôi nghĩ giải pháp này chứa quá nhiều mã trùng lặp
wong2

Có nhiều cách để giải quyết một vấn đề. Tôi chỉ đăng giải pháp của mình để khiến bạn thấy logic đằng sau cách giải quyết. Có nhiều cách để tránh trùng lặp.
Pothi Kalimuthu

4

Cách được đề xuất có thể là sử dụng a map, cũng bởi vì các biến này chỉ được đánh giá khi chúng được sử dụng.

Ngoài ra việc sử dụng return 301 ...được ưu tiên hơn viết lại, bởi vì không có biểu thức chính quy phải được biên dịch.

Dưới đây là một ví dụ về nơi mà máy chủ và tác nhân người dùng như một chuỗi nối được so sánh với một biểu thức chính:

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

Và điều này có thể còn linh hoạt hơn, ví dụ nếu không có 2 mà có nhiều tên miền liên quan.

Ở đây bản đồ chúng tôi www.domain.comvới người sử dụng các đại lý bắt đầu với Agenttới http://www.domain2.comwww.domain2.comvới chính xác user-agent 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;
  }
}

NB bạn sẽ cần nginx 0.9.0 hoặc cao hơn để chuỗi được nối trong bản đồ hoạt động.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.