ฉันจะมีกฎเดียวกันสำหรับสองสถานที่ในการกำหนดค่า NGINX ได้อย่างไร


153

ฉันจะมีกฎเดียวกันสำหรับสองสถานที่ในการกำหนดค่า NGINX ได้อย่างไร

ฉันได้ลองทำสิ่งต่อไปนี้แล้ว

server {
  location /first/location/ | /second/location/ {
  ..
  ..
  }
}

แต่การโหลดซ้ำ nginx ทำให้เกิดข้อผิดพลาดนี้:

nginx: [emerg] invalid number of arguments in "location" directive**

คำตอบ:


239

ลอง

location ~ ^/(first/location|second/location)/ {
  ...
}

~หมายถึงการใช้นิพจน์ปกติสำหรับที่ url ^หมายถึงการตรวจสอบจากตัวอักษรตัวแรก นี้จะมองหาตามด้วยสถานที่และหลังจากนั้นอีก//


37
หมายเหตุ: หากสิ่งนี้เกิดขึ้นบ่อยครั้ง (เช่นหลักพัน) มันจะต้องเสียค่าปรับเนื่องจากการจับคู่ regex ลำดับของการจับคู่นั้นแตกต่างกันอย่างมาก ในกรณี "เล็ก ๆ " จำนวนมากมันจะทำงานเหมือนที่คุณต้องการ แต่นี่เป็นสิ่งที่ควรระวัง ฉันเองต้องการ Nginx "location" เพื่อสนับสนุนเงื่อนไข "=" หลายรายการแทนที่จะใช้กฎ regex
เบอร์นาร์ด

7
IMHO สิ่งนี้ควรมีประสิทธิภาพมากขึ้น: ตำแหน่ง ~ (patternOne | patternTwo) {... }
stamster

2
วิธีนี้ไม่ได้ผลสำหรับฉัน อย่างไรก็ตามความคิดเห็นของ @ stamster ไม่ได้; ฉันกำลังวิ่งnginx/1.13.2
TJ Biddle

1
หากคุณต้องการproxy_passทำงานให้ดูคำตอบนี้: stackoverflow.com/a/46625656/1246870
avs099

1
สิ่งนี้ไม่ได้ผลสำหรับฉันเมื่อ URL ดั้งเดิมลงท้ายด้วยเครื่องหมายสแลช
The Godfather

88

ตัวเลือกอื่นคือการทำซ้ำกฎในสองคำนำหน้าสถานที่โดยใช้ไฟล์รวม เนื่องจากตำแหน่งส่วนนำหน้านั้นขึ้นอยู่กับตำแหน่งในการกำหนดค่าการใช้ตำแหน่งสามารถบันทึกความสับสนบางอย่างเมื่อคุณเพิ่มตำแหน่ง regex อื่น ๆ ในภายหลัง หลีกเลี่ยงตำแหน่ง regex เมื่อคุณสามารถช่วยปรับขนาดการกำหนดค่าของคุณได้อย่างราบรื่น

server {
    location /first/location/ {
        include shared.conf;
    }
    location /second/location/ {
        include shared.conf;
    }
}

นี่คือตัวอย่าง shared.conf:

default_type text/plain;
return 200 "http_user_agent:    $http_user_agent
remote_addr:    $remote_addr
remote_port:    $remote_port
scheme:     $scheme
nginx_version:  $nginx_version
";

คุณสามารถเพิ่มshared.confตัวอย่างและที่ตั้งได้ไหม?
ДмитрийКулешов

5
ฉันได้เพิ่มไฟล์ shared.conf ตัวอย่าง คุณสามารถใช้พา ธ สัมบูรณ์ไปยัง shared.conf หรือใส่ไว้ในไดเรกทอรี nginx ของคุณ ในกรณีนี้มันมีเพียงคำสั่งคู่
Cole Tierney

40

ทั้งไฟล์ regex และรวมเป็นวิธีการที่ดีและฉันมักจะใช้ไฟล์เหล่านั้น แต่อีกทางเลือกหนึ่งคือใช้ "ตำแหน่งที่ตั้งชื่อ" ซึ่งเป็นวิธีการที่มีประโยชน์ในหลาย ๆ สถานการณ์โดยเฉพาะอย่างยิ่งที่ซับซ้อนกว่า หน้า"If is Evil" อย่างเป็นทางการจะแสดงสิ่งต่อไปนี้เป็นวิธีที่ดีในการทำสิ่งต่าง ๆ :

error_page 418 = @common_location;
location /first/location/ {
    return 418;
}
location /second/location/ {
    return 418;
}
location @common_location {
    # The common configuration...
}

มีข้อดีและข้อเสียของวิธีการต่าง ๆ เหล่านี้ ข้อดีอย่างหนึ่งของ regex ก็คือคุณสามารถจับภาพบางส่วนของการแข่งขันและใช้เพื่อแก้ไขการตอบสนอง แน่นอนคุณมักจะสามารถบรรลุผลที่คล้ายกันด้วยวิธีการอื่น ๆ mapโดยการตั้งค่าตัวแปรในบล็อกเดิมหรือใช้ ข้อเสียของวิธีการ regex คือมันสามารถรับได้อย่างง่ายดายหากคุณต้องการจับคู่สถานที่ที่หลากหลายรวมถึงลำดับความสำคัญต่ำของ regexอาจไม่พอดีกับวิธีที่คุณต้องการจับคู่สถานที่ - ไม่พูดถึงว่ามีผลกระทบต่อประสิทธิภาพอย่างชัดเจน จาก regexes ในบางกรณี

ข้อได้เปรียบหลักของการรวมไฟล์ (เท่าที่ฉันสามารถบอกได้) คือมันมีความยืดหยุ่นมากกว่าเล็กน้อยเกี่ยวกับสิ่งที่คุณสามารถรวมได้ - มันไม่จำเป็นต้องเป็นตำแหน่งบล็อกแบบเต็มตัวอย่างเช่น แต่มันก็เป็นอะไรที่แปลกกว่าที่ตั้งชื่อ

นอกจากนี้โปรดทราบว่ามีวิธีแก้ไขปัญหาที่เกี่ยวข้องซึ่งคุณสามารถใช้ในสถานการณ์ที่คล้ายกัน: ตำแหน่งที่ซ้อนกัน แนวคิดคือคุณจะเริ่มต้นด้วยตำแหน่งทั่วไปใช้การกำหนดค่าบางอย่างร่วมกับการจับคู่ที่เป็นไปได้หลาย ๆ อันจากนั้นให้แยกตำแหน่งที่ซ้อนกันสำหรับเส้นทางประเภทต่างๆที่คุณต้องการจับคู่ ตัวอย่างเช่นอาจเป็นประโยชน์ในการทำสิ่งนี้:

location /specialpages/ {
    # some config
    location /specialpages/static/ {
        try_files $uri $uri/ =404;
    }
    location /specialpages/dynamic/ {
        proxy_pass http://127.0.0.1;
    }
}

7

นี่เป็นวิธีสั้น ๆ แต่มีประสิทธิภาพและได้รับการพิสูจน์แล้ว:

location ~ (patternOne|patternTwo){ #rules etc. }

ดังนั้นหนึ่งสามารถมีหลายรูปแบบได้อย่างง่ายดายด้วยไวยากรณ์ท่อง่าย ๆ ชี้ไปที่บล็อก / กฎสถานที่เดียวกัน

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