Question Nginx reverse proxy + réécriture d'URL


Nginx fonctionne sur le port 80 et je l'utilise pour inverser les URL de proxy avec le chemin /foo mettre en communication 3200 par ici:

location /foo {
                proxy_pass http://localhost:3200;
                proxy_redirect     off;
                proxy_set_header   Host $host;
}

Cela fonctionne bien, mais j'ai une application sur le port 3200, pour lequel je ne veux pas l'initiale /foo être envoyé à. C’est - quand j’accède http://localhost/foo/bar, Je veux seulement /bar être le chemin reçu par l'application. J'ai donc essayé d'ajouter cette ligne au bloc de localisation ci-dessus:

rewrite ^(.*)foo(.*)$ http://localhost:3200/$2 permanent;

Cela provoque 302 redirection (changement d'URL), mais je veux 301. Que dois-je faire?


95
2018-04-15 17:31


origine


Si vous avez un problème avec le cas Grafana, vous devriez utiliser cette recette: docs.grafana.org/installation/behind_proxy/… - mohsen saeedi


Réponses:


Toute redirection vers localhost n’a aucun sens depuis un système distant (par exemple, le navigateur Web du client). Alors le réécrire les drapeaux permanent (301) ou redirection (302) ne sont pas utilisables dans votre cas.

Essayez de suivre la configuration en utilisant une règle de réécriture transparente:

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
}

Utilisation curl -i pour tester vos réécritures. Un changement très subtil de la règle peut amener nginx à effectuer une redirection.


117
2018-04-15 17:56



Le chemin de l'URL commence toujours par / foo dans mon application lorsque je le fais ... - jeffreyveon
Il doit y avoir un problème différent. J'ai reproduit ce scénario avec succès, il y a quelques minutes à peine. URL d'origine: http: // development / foo / testme / 1234 - REQUEST_URI d'un script PHP s'exécutant sur un serveur Apache connecté en tant que serveur proxy: '/ testme / 1234' - Jens Bradler
La regex devrait probablement être /foo(.*), autrement example.com/foo ne sera pas jumelé. (ce qui est probablement ce que jeffreyveon a expérimenté) - Benno
Ce type de travail fonctionne, mais mon corps que je suis en train de configurer avec proxy_set_body est en train d'être supprimé. - Justin Thomas
réécrire /(.*) /socket.io/ break; GAGNEZ MON JOUR POUR SOCKET.IO - user956584


La correspondance de préfixe d'emplacement simple fonctionne pour cela sans utiliser de règle de réécriture tant que vous spécifiez un URI dans la directive proxy_pass:

location /foo {
  proxy_pass http://localhost:3200/;
}

Remarquez le supplément / à la fin de proxy_pass directif. NGINX supprimera le préfixe correspondant /foo et passez le reste au serveur principal à l'URI /. Donc, http://myserver:80/foo/bar affichera sur le backend à http://localhost:3200/bar.

Du Documents NGINX sur proxy_pass:

Si la directive proxy_pass est spécifiée avec un URI, alors quand un   requête est transmise au serveur, partie d'un URI de requête normalisée   correspondant à l'emplacement est remplacé par un URI spécifié dans la directive:


86
2017-09-29 03:30



Fonctionne pour moi que je n'ai ajouté / à l'emplacement / foo / { - Andrei N
C'était précisément ce que je cherchais! - anbiniyar
C'est une solution très propre, je préférerais que ce soit la réponse canonique à la question. - ralien
Il a fallu trop longtemps pour comprendre l’importance de conserver ou de supprimer les barres obliques. - Parvez
Cela passera réellement //xyz à l'hôte si vous faites cela. - Archimedes Trajano


La manière la plus correcte et la meilleure pratique sont généralement les suivantes:

location /foo/ {
    proxy_pass http://localhost:3200/; # note the trailing slash!
}

  • Notez la terrible importance de la slash final proxy_pass, qui modifie automatiquement le $uri variable d'avoir le /foo/ sur le front correspondent à / sur le backend. Pas besoin d'un explicite rewrite directif.

  • De plus, notez que le traînant / dans le location est également très important - sans cela, vous risqueriez d’avoir des URL étranges sur votre site à un moment donné (par exemple, un /fooen en plus de /foo/en).

    En outre, la fuite / dans le location avec proxy_pass assure également certains traitement spécial, selon la documentation du location directive, afin de provoquer efficacement une location = /foo {return 301 /foo/;} ainsi que.

    Donc, en définissant un location avec la barre oblique de fin comme ci-dessus, non seulement vous assurez-vous que les URL avec suffixe sans barre, comme /fooen ne sera pas valide, mais aussi qu'un /foo sans une barre oblique continuera à fonctionner aussi bien.


Documentation de référence:


30
2017-08-26 21:12



C'est la meilleure réponse ici! - Mo Friedrich
Ça ressemble à $args Sont perdus: http://frontend/foo?bar=baz sera mandaté à http://backend/. Notez que les arguments ne font pas partie de l'URL - Vanuan
@Vanuan, êtes-vous sûr de cela? Je suis assez certain $args doit toujours être traité de manière appropriée si vous utilisez le code ci-dessus, car ils sont distincts de $uri, et devrait être réassemblé, sauf si vous utilisez des variables explicites dans votre proxy_pass. - cnst
@ArchimedesTrajano, vous avez tort, car il existe un traitement spécial pour /foo rediriger vers /foo/Donc, à moins que vous ne fassiez quelque chose de bizarre dans le backend, même /foo les demandes fonctionneront toujours avec le code ci-dessus. (En fait, cela fait déjà partie de la réponse, BTW.) - cnst
C'est la meilleure réponse! Cela doit monter. - phegde


essayer

location /foo {
    proxy_pass http://localhost:3200/;
    ....

ou

location ^~ /foo {
    proxy_pass http://localhost:3200/;
    ....

0
2018-01-21 16:20



Cette réponse serait utile si vous expliquez pourquoi elle doit être configurée comme ci-dessus. - masegaloeh
Cela passera réellement //xyz à l'hôte si vous faites cela. - Archimedes Trajano