Nginx fonctionne sur le port 80 et je l'utilise pour inverser les URL de proxy avec le chemin /foo
d' accès au port de 3200
cette façon:
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 laquelle je ne veux pas que l'initiale /foo
soit envoyée. C’est-à-dire que, lorsque 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?
nginx
reverse-proxy
301-redirect
Jeffreyveon
la source
la source
Réponses:
Toute redirection vers localhost n'a pas de sens depuis un système distant (par exemple, le navigateur Web du client). Ainsi, les indicateurs de réécriture permanents (301) ou de redirection (302) ne sont pas utilisables dans votre cas.
Essayez de suivre la configuration en utilisant une règle de réécriture transparente:
Utilisez
curl -i
pour tester vos réécritures. Un changement très subtil de la règle peut amener nginx à effectuer une redirection.la source
/foo(.*)
, sinonexample.com/foo
ne seront pas appariés. (ce qui est probablement ce que jeffreyveon a connu)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:
Remarquez le supplément
/
à la fin de laproxy_pass
directive. NGINX supprimera le préfixe correspondant/foo
et transmettra le reste au serveur principal à l'URI/
. Par conséquent,http://myserver:80/foo/bar
publierons sur le backend àhttp://localhost:3200/bar
.À partir de la documentation NGINX sur proxy_pass :
la source
//xyz
à l'hôte si vous faites cela.La manière la plus correcte et la meilleure pratique sont généralement les suivantes:
Notez la très grande importance de la barre oblique finale
proxy_pass
, qui modifie automatiquement la$uri
variable pour faire correspondre le/foo/
côté frontal avec/
le fond. Pas besoin derewrite
directive explicite .De plus, notez que la fin
/
de lalocation
est aussi très importante dans le - sans cela, vous risqueriez d’avoir des URL bizarres sur votre site à un moment donné (par exemple, un travail/fooen
en plus de/foo/en
).De plus, la fin
/
dans lelocation
avecproxy_pass
assure également un traitement spécial , conformément à la documentation de lalocation
directive, pour générer efficacement une implicitelocation = /foo {return 301 /foo/;}
.Ainsi, en définissant un
location
avec la barre oblique finale comme ci-dessus, vous garantissez non seulement que les URL de type suffixe sans barre oblique ne/fooen
seront pas valables, mais également qu’une/foo
barre oblique sans fin continuera à fonctionner également.Documentation de référence:
la source
$args
sont perdus: ilshttp://frontend/foo?bar=baz
seront représentés par un proxyhttp://backend/
. Notez que les arguments ne font pas partie de l'URL$args
devriez quand même utiliser le code ci-dessus, car ils sont distincts$uri
et doivent être réassemblés, sauf si vous utilisez des variables explicites dans votreproxy_pass
./foo
redirection vers/foo/
. Par conséquent, à moins que vous ne fassiez quelque chose de bizarre dans le backend, même les/foo
demandes fonctionneront toujours avec le code ci-dessus. (C'est en fait déjà une partie de la réponse, BTW.)essayer
ou
la source
//xyz
à l'hôte si vous faites cela.@Terabuck Désolé de ne pas avoir encore répondu.
Vous ne devez pas utiliser localhost car vous dépendez du fait que l'application s'exécute sur un serveur avec un fichier hosts. hôte local est seulement une traduction par défaut à 127.0.0.1. Rien n'indique que vous devez avoir ces fichiers hôtes. C'est très courant d'en avoir un.
Avoir une interface de bouclage est encore une autre chose commune, mais vous dépendez toujours de l'interface de bouclage sur la pile de mise en réseau. C'est un cas rare de ne pas avoir ces deux. Si jamais vous vous inquiétez de cela. Au moins sur unix / linux, vous avez l’option pour les sockets. Cela éliminera le besoin de la pile réseau pour atteindre l'hôte local. Soyez prudent avec cette approche car il y a quelques facteurs qui seront mis en place sur le système d'exploitation hôte. Tels que le nombre de fichiers ouverts, etc.
la source