Làm cách nào tôi có thể có cùng quy tắc cho hai vị trí trong cấu hình NGINX?


153

Làm cách nào tôi có thể có cùng quy tắc cho hai vị trí trong cấu hình NGINX?

Tôi đã thử như sau

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

nhưng nginx tải lại lỗi này:

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

Câu trả lời:


238

Thử

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

Các ~phương tiện để sử dụng một biểu thức thông thường cho url. Các ^phương tiện để kiểm tra từ ký tự đầu tiên. Điều này sẽ tìm kiếm /theo sau bởi một trong hai vị trí và sau đó là một vị trí khác /.


37
LƯU Ý: nếu điều này xảy ra thường xuyên (như hàng ngàn), nó sẽ bị phạt hiệu suất do khớp regex. Ngoài ra thứ tự phù hợp là khác nhau đáng kể. Trong rất nhiều trường hợp "nhỏ", nó sẽ hoạt động như bạn muốn, nhưng đây là điều cần lưu ý. Cá nhân tôi muốn "vị trí" của Nginx hỗ trợ nhiều điều kiện "=" thay vì dựa vào quy tắc regex.
Bernard

7
IMHO, điều này sẽ hiệu quả hơn: location ~ (patternOne | patternTwo) {...}
stamster

2
Giải pháp này không hiệu quả với tôi; tuy nhiên bình luận của @ stamster đã làm; Tôi đang chạynginx/1.13.2
TJ Biddle

1
nếu bạn cần proxy_passlàm việc, hãy xem câu trả lời sau: stackoverflow.com/a/46625656/1246870
avs099

1
Điều này không hiệu quả với tôi khi URL ban đầu kết thúc mà không có dấu gạch chéo
Bố già

88

Một tùy chọn khác là lặp lại các quy tắc ở hai vị trí tiền tố bằng cách sử dụng một tệp được bao gồm. Vì các vị trí tiền tố là vị trí độc lập trong cấu hình, sử dụng chúng có thể tiết kiệm một số nhầm lẫn khi bạn thêm các vị trí regex khác sau này. Tránh các vị trí regex khi bạn có thể giúp quy mô cấu hình của bạn trơn tru.

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

Đây là một mẫu được chia sẻ.

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

bạn có thể thêm shared.confví dụ và vị trí?
Tôi đã làm việc vào

5
Tôi đã thêm một ví dụ về tập tin shared.conf. Bạn có thể sử dụng một đường dẫn tuyệt đối đến shared.conf hoặc đặt nó vào thư mục nginx của bạn. Trong trường hợp này, nó chỉ chứa một vài chỉ thị.
Cole Tierney

40

Cả tệp regex và tệp đi kèm đều là các phương thức tốt và tôi thường xuyên sử dụng các tệp đó. Nhưng một cách khác là sử dụng "vị trí được đặt tên", đây là một cách tiếp cận hữu ích trong nhiều tình huống - đặc biệt là những vị trí phức tạp hơn. Trang "If is Evil" chính thức hiển thị về cơ bản như sau đây là một cách tốt để làm mọi việc:

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

Có những lợi thế và bất lợi cho các phương pháp khác nhau. Một lợi thế lớn cho regex là bạn có thể nắm bắt các phần của trận đấu và sử dụng chúng để sửa đổi phản hồi. Tất nhiên, bạn thường có thể đạt được kết quả tương tự với các phương pháp khác bằng cách đặt biến trong khối ban đầu hoặc sử dụng map. Nhược điểm của phương pháp regex là nó có thể trở nên khó sử dụng nếu bạn muốn kết hợp nhiều vị trí khác nhau, cộng với mức độ ưu tiên thấp của regex có thể không phù hợp với cách bạn muốn khớp với các vị trí - không đề cập đến việc có các tác động hiệu suất rõ ràng từ regexes trong một số trường hợp.

Ưu điểm chính của việc bao gồm các tệp (theo như tôi có thể nói) là nó linh hoạt hơn một chút về chính xác những gì bạn có thể bao gồm - ví dụ, nó không phải là một khối vị trí đầy đủ. Nhưng nó cũng chủ quan hơn một chút so với các địa điểm được đặt tên.

Cũng lưu ý rằng có một giải pháp liên quan mà bạn có thể sử dụng trong các tình huống tương tự: vị trí lồng nhau. Ý tưởng là bạn sẽ bắt đầu với một vị trí rất chung, áp dụng một số cấu hình phổ biến cho một số kết quả khớp có thể và sau đó có các vị trí lồng nhau cho các loại đường dẫn khác nhau mà bạn muốn khớp. Ví dụ, có thể hữu ích khi làm một cái gì đó như thế này:

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

7

Đây là cách tiếp cận ngắn, nhưng hiệu quả và đã được chứng minh:

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

Vì vậy, người ta có thể dễ dàng có nhiều mẫu với cú pháp ống đơn giản chỉ đến cùng một khối / quy tắc vị trí.

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.