Bagaimana saya bisa memiliki aturan yang sama untuk dua lokasi di konfigurasi NGINX?

153

Bagaimana saya bisa memiliki aturan yang sama untuk dua lokasi di konfigurasi NGINX?

Saya sudah mencoba yang berikut ini

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

tetapi nginx reload melemparkan kesalahan ini:

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

Jawaban:

239

Mencoba

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

Cara ~untuk menggunakan ekspresi reguler untuk url. The ^sarana untuk memeriksa dari karakter pertama. Ini akan mencari /diikuti oleh salah satu lokasi dan kemudian yang lain /.

ketiak
sumber
37
CATATAN: jika ini sering terjadi (seperti ribuan), itu akan dikenakan penalti kinerja karena pencocokan regex. Juga urutan pencocokan secara substansial berbeda. Dalam banyak kasus "kecil", itu akan berperilaku seperti yang Anda inginkan, tetapi ini adalah sesuatu yang perlu diperhatikan. Saya pribadi ingin Nginx "location" mendukung banyak kondisi "=" alih-alih mengandalkan aturan regex.
Bernard
7
IMHO, ini harus lebih efisien: lokasi ~ (patternOne | patternTwo) {...}
stamster
2
Solusi ini tidak berhasil untuk saya; Namun, komentar @ stamster memang; Saya menjalankannginx/1.13.2
TJ Biddle
1
jika Anda perlu proxy_passbekerja, lihat jawaban ini: stackoverflow.com/a/46625656/1246870
avs099
1
Ini tidak berfungsi untuk saya ketika URL asli berakhir tanpa garis miring
The Godfather
88

Pilihan lain adalah mengulang aturan di dua lokasi awalan menggunakan file yang disertakan. Karena lokasi awalan adalah posisi independen dalam konfigurasi, menggunakannya dapat menyimpan beberapa kebingungan saat Anda menambahkan lokasi regex lain di kemudian hari. Menghindari lokasi regex saat Anda dapat membantu skala konfigurasi Anda dengan lancar.

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

Berikut ini contoh 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
";
Cole Tierney
sumber
dapatkah Anda menambahkan shared.confcontoh dan lokasi?
Дмитрий Кулешов
5
Saya telah menambahkan contoh file shared.conf. Anda dapat menggunakan path absolut ke shared.conf atau meletakkannya di direktori nginx Anda. Dalam hal ini, itu hanya berisi arahan pasangan.
Cole Tierney
40

Baik regex dan file yang disertakan adalah metode yang baik, dan saya sering menggunakannya. Tetapi alternatif lain adalah dengan menggunakan "nama lokasi", yang merupakan pendekatan yang berguna dalam banyak situasi - terutama yang lebih rumit. Halaman resmi "If is Evil" pada dasarnya menunjukkan hal berikut sebagai cara yang baik untuk melakukan sesuatu:

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

Ada keuntungan dan kerugian dari berbagai pendekatan ini. Satu keuntungan besar bagi regex adalah Anda dapat menangkap bagian dari pertandingan dan menggunakannya untuk mengubah respons. Tentu saja, Anda biasanya dapat mencapai hasil yang serupa dengan pendekatan lain dengan mengatur variabel di blok asli atau menggunakan map. Kelemahan dari pendekatan regex adalah bisa menjadi berat jika Anda ingin mencocokkan berbagai lokasi, ditambah rendahnya prioritas regex mungkin tidak cocok dengan bagaimana Anda ingin mencocokkan lokasi - belum lagi bahwa tampaknya ada dampak kinerja dari regex dalam beberapa kasus.

Keuntungan utama dari memasukkan file (sejauh yang saya tahu) adalah sedikit lebih fleksibel tentang apa yang dapat Anda sertakan - misalnya, tidak harus berupa blok lokasi penuh. Tapi itu juga hanya sedikit lebih klakson daripada lokasi yang disebutkan.

Perhatikan juga bahwa ada solusi terkait yang mungkin dapat Anda gunakan dalam situasi serupa: lokasi bersarang. Idenya adalah Anda akan mulai dengan lokasi yang sangat umum, menerapkan beberapa konfigurasi yang umum untuk beberapa kecocokan yang mungkin, dan kemudian memiliki lokasi bersarang terpisah untuk berbagai jenis jalur yang ingin Anda cocokkan. Misalnya, mungkin berguna untuk melakukan sesuatu seperti ini:

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

Ini adalah pendekatan yang singkat, namun efisien dan terbukti:

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

Jadi seseorang dapat dengan mudah memiliki beberapa pola dengan sintaksis pipa sederhana yang menunjuk ke blok / aturan lokasi yang sama.

stamster
sumber