Dans Nginx, nous avons essayé de rediriger une URL comme suit:
http://example.com/some/path -> http://192.168.1.24
où l'utilisateur voit toujours l'URL d'origine dans son navigateur. Une fois l'utilisateur redirigé, dites qu'il clique sur le lien vers /section/index.html
, nous souhaitons que cela fasse une demande qui mène à la redirection
http://example.com/some/path/section/index.html -> http://192.168.1.24/section/index.html
et encore une fois conserver l'URL d'origine.
Nos tentatives ont impliqué diverses solutions utilisant des proxys et des règles de réécriture, et ci-dessous montre la configuration qui nous a rapprochés le plus d'une solution (notez qu'il s'agit de la configuration du serveur Web pour le example.com
serveur Web). Cependant, il y a toujours deux problèmes avec ceci:
http://192.168.1.24
comprend /some/path
et ne parvient donc pas à diffuser la page requise.Lorsque vous survolez un lien une fois qu'une page a été diffusée, /some/path
est absent de l'URL
server {
listen 80;
server_name www.example.com;
location /some/path/ {
proxy_pass http://192.168.1.24;
proxy_redirect http://www.example.com/some/path http://192.168.1.24;
proxy_set_header Host $Host;
}
location / {
index index.html;
root /var/www/example.com/htdocs;
}
}
Nous recherchons une solution qui implique uniquement de modifier la configuration du serveur Web sur example.com
. Nous pouvons changer la configuration sur 192.168.1.24
(également Nginx), mais nous voulons essayer d'éviter cela car nous devrons répéter cette configuration pour des centaines de serveurs différents dont l'accès est mandaté via example.com
.
Tout d'abord, vous ne devez pas utiliser la directive root
à l'intérieur du bloc d'emplacement, c'est une mauvaise pratique. Dans ce cas, cela n'a pas d'importance cependant.
Essayez d'ajouter un deuxième bloc d'emplacement:
location ~ /some/path/(?<section>.+)/index.html {
proxy_pass http://192.168.1.24/$section/index.html;
proxy_set_header Host $Host;
}
Cela capture la partie après/some/path/et avant index.html dans une variable $ section, qui est ensuite utilisée pour définir la destination proxy_pass. Vous pouvez rendre l'expression régulière plus spécifique si vous en avez besoin.
Vous devez utiliser la partie URI dans proxy_pass
directive. De plus, vous avez mélangé les arguments d'ordre de proxy_redirect
directive, et vous n'en avez probablement pas besoin du tout. Nginx a une valeur par défaut raisonnable pour cette directive.
Dans ce cas, votre bloc location
pourrait être très simple:
location /some/path/ {
proxy_pass http://192.168.1.24/;
# note this slash -----------^
proxy_set_header Host $Host;
}
Vous pouvez utiliser la configuration suivante pour avoir un mappage 100% transparent entre /some/path/
sur le front-end et /
sur le backend.
Notez que c'est la seule réponse à ce jour qui prendrait également en charge de manière transparente les chemins absolus générant 404 Not Found
erreurs, à condition que l'en-tête HTTP Referer
correct soit envoyé par le navigateur, donc, tous ces gifs devraient continuer à se charger sans avoir besoin de modifier le HTML sous-jacent (ce qui est non seulement cher, mais n'est pas non plus pris en charge sans modules supplémentaires non compilés par défaut).
location /some/path/ {
proxy_pass http://192.168.1.24/; # note the trailing slash!
}
location / {
error_page 404 = @404;
return 404; # this would normally be `try_files` first
}
location @404 {
add_header Vary Referer; # sadly, no effect on 404
if ($http_referer ~ ://[^/]*(/some/path|/the/other)/) {
return 302 $1$uri;
}
return 404 "Not Found\n";
}
Vous pouvez trouver la preuve de concept complète et le produit viable minimal dans le https://github.com/cnst/StackOverflow.cnst.nginx.conf référentiel .
Voici un test pour confirmer que tous les cas Edge semblent fonctionner:
curl -v -H 'Referer: http://example.su/some/path/page.html' localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
> Referer: http://example.su/some/path/page.html
< HTTP/1.1 302 Moved Temporarily
< Location: http://localhost:6586/some/path/and/more.gif
< Vary: Referer
curl -v localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
< HTTP/1.1 404 Not Found
curl -v localhost:6586/some/path/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location -e uri
> GET /some/path/and/more.gif HTTP/1.1
< HTTP/1.1 200 OK
request_uri: /and/more.gif
P.S. Si vous avez beaucoup de chemins différents à mapper, au lieu de faire une comparaison regex de $http_referer
dans un if
dans location @404
, vous souhaiterez peut-être utiliser à la place la directive map
globale.
Notez également que les barres obliques de fin dans le proxy_pass
, ainsi que le location
dans lequel il est contenu, sont très importants selon une réponse connexe .
Références:
Lorsque cette barre oblique est ajoutée à un jenkins proxy Nginx, vous voyez s'afficher l'erreur "Il semble que la configuration de votre proxy inverse est rompue".
proxy_pass http://localhost:8080/;
Remove this -----------------------------^
Il faut lire
proxy_pass http://localhost:8080;