Frage Nginx Reverse Proxy + URL Neuschreiben


Nginx wird auf Port 80 ausgeführt, und ich verwende es, um Proxy-URLs mit Pfad umzukehren /foo zum Hafen 3200 diesen Weg:

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

Das funktioniert gut, aber ich habe eine Anwendung auf Port 3200, für die ich die Initiale nicht will /foo zu gesendet werden. Das ist - wenn ich darauf zugreife http://localhost/foo/barIch will nur /bar der Pfad sein, wie er von der App empfangen wird. Also habe ich versucht, diese Zeile zum obigen Block hinzuzufügen:

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

Dies verursacht 302 Redirect (Änderung der URL), aber ich möchte 301. Was soll ich tun?


95
2018-04-15 17:31


Ursprung


Wenn Sie ein Problem mit Grafana haben, sollten Sie dieses Rezept verwenden: docs.grafana.org/installation/behind_proxy/... - mohsen saeedi


Antworten:


Jede Umleitung zu localhost ist von einem entfernten System (z. B. dem Webbrowser des Clients) nicht sinnvoll. Also die Flaggen umschreiben Permanent (301) oder Redirect (302) sind in Ihrem Fall nicht verwendbar.

Bitte versuchen Sie das folgende Setup mit einer transparenten Rewrite-Regel:

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

Benutzen curl -i um deine Überschreibungen zu testen. Eine sehr subtile Änderung der Regel kann dazu führen, dass nginx eine Umleitung ausführt.


117
2018-04-15 17:56



Der URL-Pfad beginnt immer noch mit / foo in meiner App, wenn ich das tue ... - jeffreyveon
Es muss ein anderes Problem geben. Ich habe dieses Szenario vor wenigen Minuten erfolgreich reproduziert. Ursprüngliche URL: http: // entwicklung / foo / testme / 1234 - REQUEST_URI eines PHP-Skripts, das auf einem Apache ausgeführt wird, der als Proxy-Back-End verbunden ist: '/ testme / 1234' - Jens Bradler
Die Regex sollte wahrscheinlich sein /foo(.*), Andernfalls example.com/foo wird nicht zusammenpassen. (was wahrscheinlich Jeffreyveon erlebt hat) - Benno
Diese Art von Arbeiten, aber mein Körper, den ich mit proxy_set_body setze, wird entfernt. - Justin Thomas
umschreiben /(.*) /socket.io/ break; Speichern Sie meinen Tag für SOCKET.IO - user956584


Der einfache Standort-Präfix-Abgleich funktioniert dafür, ohne eine Umschreibungsregel zu verwenden, solange Sie einen URI in der proxy_pass-Direktive angeben:

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

Beachten Sie die zusätzlichen / am Ende von proxy_pass Richtlinie. NGINX entfernt das übereinstimmende Präfix /foo und den Rest an den Backend-Server am URI übergeben /. Deshalb, http://myserver:80/foo/bar wird an das Backend an posten http://localhost:3200/bar.

Von dem NGINX-Dokumentation auf proxy_pass:

Wenn die Direktive proxy_pass mit einem URI angegeben ist, dann wenn a   Anfrage wird an den Server übergeben, der Teil eines normalisierten Anfrage-URIs   Der passende Ort wird durch einen in der Direktive angegebenen URI ersetzt:


86
2017-09-29 03:30



Funktioniert für mich, als ich / location / foo / {hinzugefügt habe - Andrei N
Genau danach habe ich gesucht! - anbiniyar
Das ist eine sehr saubere Lösung, ich würde es vorziehen, dies als kanonische Antwort auf die Frage zu sehen. - ralien
Es dauerte zu lange, um die Bedeutung des Beibehaltens oder Entfernens eines Schrägstrichs zu erkennen. - Parvez
Dies wird tatsächlich passieren //xyz an den Host, wenn Sie das tun. - Archimedes Trajano


Der absolut korrekteste Weg und die beste Vorgehensweise ist normalerweise wie folgt:

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

  • Beachten Sie die große Bedeutung der Schrägstrich in proxy_pass, die automatisch die ändert $uri Variable, um das zu haben /foo/ am Frontend entsprechen / auf dem Backend. Keine Notwendigkeit für eine explizite rewrite Richtlinie.

  • Beachten Sie außerdem, dass der schleppend / in dem location ist auch sehr wichtig - ohne sie riskieren Sie seltsam aussehende URLs auf Ihrer Website an einem Punkt (z. B. eine Arbeit /fooen zusätzlich zu /foo/en).

    Zusätzlich das Nachlaufende / in dem location mit proxy_pass sorgt auch für einiges besondere Behandlung, wie in der Dokumentation der location Richtlinie, um effektiv eine implizite zu verursachen location = /foo {return 301 /foo/;} auch.

    Also, indem man a location Mit dem nachgestellten Schrägstrich sorgen Sie nicht nur dafür, dass slash-lose Suffix-URLs wie /fooen wird nicht gültig sein, aber auch das a /foo ohne einen Schrägstrich wird auch weiterhin funktionieren.


Referenzdokumentation:


30
2017-08-26 21:12



Das ist die beste Antwort hier! - Mo Friedrich
Es sieht aus wie $args sind verloren: http://frontend/foo?bar=baz wird umgeleitet werden http://backend/. Beachten Sie, dass Argumente nicht Teil der URL sind - Vanuan
@ Vanuan, bist du dir da sicher? Ich bin mir ziemlich sicher $args sollte immer noch ordnungsgemäß behandelt werden, wenn Sie den obigen Code verwenden, da sie getrennt sind $uriund sollte wieder zusammengebaut werden, es sei denn, Sie verwenden explizite Variablen in Ihrem proxy_pass. - cnst
@ArchimedesTrajano, Sie sind falsch, da gibt es spezielle Handhabung für /foo umleiten zu /foo/also, es sei denn, du machst etwas Seltsames auf dem Backend, sogar /foo Anfragen funktionieren immer noch mit dem obigen Code. (Das ist eigentlich schon ein Teil der Antwort, BTW.) - cnst
Das ist die beste Antwort! Dies muss nach oben gehen. - phegde


Versuchen

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

oder

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

0
2018-01-21 16:20



Diese Antwort wäre gut, wenn Sie erklären, warum sie wie oben konfiguriert werden muss. - masegaloeh
Dies wird tatsächlich passieren //xyz an den Host, wenn Sie das tun. - Archimedes Trajano