web-dev-qa-db-fra.com

Comment puis-je créer un emplacement dans nginx qui fonctionne avec AND sans barre oblique de fin?

En ce moment, j'ai cette config:

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

Cependant, si je visite www.mysite.com/phpmyadmin (notez l'absence de barre oblique de fin), il ne trouvera pas ce que je recherche pour un 404. Je suppose que je n'inclue pas la barre oblique de fin. Comment puis-je réparer cela?

52
Rob

Cela pourrait être dans l'expression régulière que vous utilisez -

location ~ ^/phpmyadmin/(.*)$

Ce qui précède correspondra à/phpmyadmin /,/phpmyadmin/rien/autre/ici, mais il ne correspondra pas à/phpmyadmin car l'expression régulière inclut la barre oblique de fin.

Vous voulez probablement quelque chose comme ça:

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

Le point d'interrogation est un quantificateur d'expression régulière et doit indiquer à nginx de correspondre à zéro ou à l'un des caractères précédents (la barre oblique).

Attention: La communauté a vu cette solution telle quelle, comme un risque de sécurité possible

38
haymaker

La meilleure solution:

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

Assurez-vous que le serveur est autorisé à /home/phpmyadmin première.


Explication de la différence avec la réponse acceptée:

Il s'agit de expressions régulières .

Tout d'abord, le ^ char signifie que vous voulez faire correspondre depuis le début de la chaîne et non quelque part au milieu. Le $ à la fin signifie correspondre à la fin de la chaîne.

Le (?:) signifie groupe non capturant - nous ne le voulons pas dans les résultats de capture, mais nous voulons simplement regrouper quelques caractères. Nous le regroupons comme ceci, parce que nous voulons que le / char doit être une partie non significative du chemin enfant et non une partie significative du chemin parent.

39
kbec

Pourquoi ne pas simplement utiliser

location /phpmyadmin {
    alias /home/phpmyadmin;
}

?

8
womble

Je sais que c'est une vieille question, mais pour tous ceux qui se retrouvent ici via Google, je l'ai résolue de la manière suivante (variation de celle de @ kbec, qui était assez bonne):

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

Cela capturera toute variation de /foo et redirigez-le vers /bar sur une autre URL (y compris les paramètres). Je le montre avec un proxy_pass directive mais cela fonctionnerait également avec alias.

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

Cela fonctionne parce que $1 capturera éventuellement les sous-ressources plus la barre oblique principale, donc il ne capturera pas des choses comme /fooextra/. Il redirigera également correctement une barre oblique actuelle ou non présente.

7
dlouzan

Cette redirection niquement réécrira les URL avec et sans la barre oblique de fin. Tout ce qui vient après la barre oblique ne sera pas écrasé.

domain.com/location => redirigé vers domain.com/new/location
domain.com/location => redirigé vers domain.com/new/location
domain.com/location/other => non redirigé

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

Avez-vous essayé d'utiliser try_files directive?

try_files $uri $uri/ =404;
1
Prasanth

Je l'ai fait comme ça

rewrite ^/promo/?$     http://example.com/promo/page43902.html;
location /promo/ {
    root /var/www;
}
0
user3132194

Pourquoi ne pas mettre simplement deux réécritures:

location ~ ^/phpmyadmin
{
    rewrite /phpmyadmin /home/phpmyadmin/ break;
    rewrite /phpmyadmin/(.*) /home/phpmyadmin/$1 break;
}
0
千木郷