Як я можу створити місцеположення в nginx, яке працює з AND без останньої косої риски?


46

Зараз у мене є така конфігурація:

location ~ ^/phpmyadmin/(.*)$
{
        alias /home/phpmyadmin/$1;
}

Однак якщо я відвідаю www.mysite.com/phpmyadmin(зверніть увагу на відсутність косої косої риси), він не знайде те, що я шукаю 404. Я припускаю, тому що я не включаю кінцеву косу рису. Як я можу це виправити?


2
Я знаю, що це питання досить давнє, проте я хотів би наголосити на необхідності зміни прийнятої відповіді. Недосвідчені користувачі (ті, хто шукатиме такого роду QA) можуть створити отвори в безпеці за допомогою прийнятої відповіді.
Bozzy

Відповіді:


34

Це може бути в звичайному виразі, який ви використовуєте -

location ~ ^/phpmyadmin/(.*)$

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

Ви, мабуть, хочете щось подібне:

location ~ /phpmyadmin/?(.*)$ {
    alias /home/phpmyadmin/$1;
}

Знак питання є кількісним кількісним показником виразів і повинен повідомити nginx, що відповідає нулю або одному з попередніх символів (косою рискою).

Попередження: Громада бачила це рішення як можливий ризик для безпеки


Дякую! І дякую вам за пояснення. Це стане в нагоді в майбутньому.
Роб

15
Шаблон не зовсім правильний. Він також може відповідати шляху, як "/ phpmyadmin1234", очевидно, це не те, що ви хочете. @ рішення kbec є правильним.
Мяу

3
Вибачте за те, що явно заборонив це, але коментар @Meow - це важливий спосіб нехтувати. Це може призвести до неправильно налаштованого веб-сервера, який може містити отвори в безпеці.
Даніель Ф

34

Краще рішення:

location ~ ^/phpmyadmin(?:/(.*))?$ {
    alias /home/phpmyadmin/$1;
}

Переконайтеся, що /home/phpmyadminперший сервер має дозволи .


Пояснення різниці із прийнятою відповіддю:

Вся справа в регулярних виразах .

Перш за все, ^char означає, що ви хочете відповідати з початку рядка, а не десь посередині. В $кінці означає відповідність кінці рядка.

Це (?:)означає, що група, яка не захоплює, ми не хочемо, щоб це було в результатах захоплення, але ми хочемо просто згрупувати деякі символи. Ми групуємо його так, оскільки хочемо, /щоб ця картка була несуттєвою частиною дочірнього шляху, а не значною частиною батьківського шляху.


Чому краще?
Meekohi

2
@Meow відповів на це прийнятою відповіддю
kbec

2
Це має бути прийнята відповідь
Йонн Триморе

@Meekohi Я написав пояснення
kbec

8

Чому б ти просто не скористався

location /phpmyadmin {
    alias /home/phpmyadmin;
}

?


Тому що це не працювало для мене. Дивіться тут: serverfault.com/questions/375602/…
Роб

1
@Rob Ви спробували це без кінцевої косої риски aliasдирективи?
Шейн Медден

Це насправді правильна відповідь і правильний спосіб зробити це. Просто виключіть косуй косу рису, і вона працює для URL-адрес, введених як і без косої риски. Не потрібно нічого ускладнювати на Nginx, щоб просто, складний регулярний вираз та інші смішні речі лише уповільнили Nginx.
MitchellK

4
Проблема в цьому полягає в тому, що він також збігатиметься на /phpmyadminblahblahblahblahбудь-яку іншу комбінацію
Gary Green

6

Я знаю, що це старе питання, але для тих, хто опинився тут через Google, я вирішив його наступним чином (варіація @ kbec, яка була досить непоганою):

location ~ ^/foo(/.*)?$ {
  proxy_pass http://$backend$1$is_args$args
}

Це дозволить зафіксувати будь-які зміни /fooта перенаправити його /barна інший URL (включаючи параметри). Я показую це з proxy_passдирективою, але це також буде працювати alias.

  • /foo -> /bar
  • /foo/ -> /bar/
  • /foo/sub -> /bar/sub
  • /foo/sub1/sub2/?param=value -> /bar/sub1/sub2/?param=value

Він працює, тому що $1необов'язково захопить субресурси плюс провідну косу рису, тому він не захопить такі речі /fooextra/. Він також буде належним чином перенаправляти подану або неіснуючу кінцеву косу рису.


1
Дякуємо, що розглядали головний випадок, коли хочете використовувати proxy_pass і, таким чином, дбаючи про аргументи. Ви маєте мою підтримку.
Даніель Ф

2

Це переспрямування буде перезаписати лише URL-адреси з та без косої риски. Все, що з’явиться після косої риски, не буде перезаписано.

domain.com/location => переспрямовано на domain.com/new/location
domain.com/location => перенаправлено на domain.com/new/location
domain.com/location/other => не перенаправлено

server {
  # 301 URL Redirect
  rewrite ^/location/?$ /new/location permanent;
}



0

Чому б не поставити два переписки просто:

location ~ ^/phpmyadmin
{
    rewrite /phpmyadmin /home/phpmyadmin/ break;
    rewrite /phpmyadmin/(.*) /home/phpmyadmin/$1 break;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.