การเปลี่ยนเส้นทาง 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.comและwww.domain2.comแสดงเนื้อหาเดียวกัน

ตอนนี้ฉันต้องการเพิ่ม

หากผู้ใช้เยี่ยมชม www.domain.com และตัวแทนผู้ใช้คือ xxx ให้เปลี่ยนเส้นทางไปที่ www.domain2.com

ฉันค้นหาและลองใช้วิธีการจำนวนมากแล้ว แต่ก็ไม่มีวิธีใดทำงานได้


คุณยังต้องการแสดงเนื้อหาเดียวกันแม้หลังจากเปลี่ยนเส้นทางหรือไม่
Pothi Kalimuthu

@Pothi ใช่แน่นอน
wong2

ตกลง. โปรดตรวจสอบคำตอบของฉัน
Pothi Kalimuthu

คำตอบ:


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

วิธีที่แนะนำอาจจะใช้ a map, เพราะตัวแปรเหล่านี้จะถูกประเมินเมื่อมีการใช้งานเท่านั้น

นอกจากนี้ยังมีการใช้งานreturn 301 ...ที่ต้องการมากกว่าการเขียนใหม่เพราะไม่มีการรวบรวมการแสดงออกปกติ

นี่คือตัวอย่างของการที่ host และ user-agent เป็นสตริงที่ต่อกันถูกเปรียบเทียบกับ regex เดี่ยว:

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 โดเมน

ที่นี่เรา map www.domain.comกับตัวแทนผู้ใช้เริ่มต้นด้วยการAgentไปhttp://www.domain2.comและwww.domain2.comกับที่แน่นอน 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คุณจะต้องใช้ nginx 0.9.0 หรือสูงกว่าเพื่อให้สตริงที่ต่อกันในแผนที่ทำงานได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.