Як я можу мати одне правило для двох місць у конфігурації 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
ПРИМІТКА: якщо це трапляється часто (наприклад, тисячі), воно спричинить штрафи за ефективність через збіг регулярних виразів. Також порядок узгодження істотно відрізняється. У багатьох "маленьких" випадках вона буде вести себе так, як вам хочеться, але це те, про що слід пам’ятати. Я особисто хочу, щоб Nginx "location" підтримував декілька умов "=", а не покладався на правило регулярного вираження.
Бернар

7
ІМХО, це має бути ефективнішим: розташування ~ (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

Інший варіант - повторити правила у двох місцях префіксу, використовуючи доданий файл. Оскільки розташування префіксів у конфігурації не залежать від позиції, їх використання може зберегти певну плутанину, коли ви додасте інші місця повторного виведення. Якщо ви зможете уникати географічних локацій, ви зможете плавно змінювати масштаб конфігурації.

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. У цьому випадку він просто містить пару директив.
Коул Тірні

40

І регекс, і файли, що додаються, є хорошими методами, і я часто їх використовую. Але іншою альтернативою є використання "названого місця", що є корисним підходом у багатьох ситуаціях - особливо складніших. Офіційний «Якщо це зло» сторінка показує , по суті, такі як хороший спосіб робити речі:

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

У цих різних підходів є переваги та недоліки. Одна велика перевага для регулярного вираження полягає в тому, що ви можете захоплювати частини матчу та використовувати їх для зміни відповіді. Звичайно, зазвичай можна досягти подібних результатів з іншими підходами, встановивши змінну в початковому блоці або використовуючи map. Недоліком підходу регулярного вираження є те, що він може стати непростим, якщо ви хочете відповідати різним місцеположенням, плюс низький пріоритет регулярного виразів може просто не відповідати тому, як ви хочете співставити місця - не кажучи вже про те, що очевидно впливають на ефективність від регулярних виразів у деяких випадках.

Основна перевага включення файлів (наскільки я можу сказати) полягає в тому, що він трохи гнучкіший щодо того, що саме ви можете включити - наприклад, це не повинно бути блоком повного місцезнаходження. Але це також просто суб'єктивно трохи незграбніше, ніж названі місця.

Також зауважте, що існує відповідне рішення, яке ви можете використовувати в подібних ситуаціях: вкладені місця. Ідея полягає в тому, що ви б почали з дуже загального розташування, застосували певну конфігурацію, спільну для кількох можливих збігів, а потім мали б окремі вкладені місця для різних типів шляхів, які ви хочете зіставити. Наприклад, може бути корисно зробити щось подібне:

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

Таким чином, можна легко мати декілька шаблонів, за допомогою простого синтаксису труби, що вказує на один блок / правила розташування.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.