Vraag Nginx reverse proxy + URL rewrite


Nginx wordt uitgevoerd op poort 80 en ik gebruik het om proxy-URL's met pad om te keren /foo naar de haven 3200 op deze manier:

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

Dit werkt prima, maar ik heb een applicatie op poort 3200, waarvoor ik de initiaal niet wil /foo verzonden worden naar. Dat is - wanneer ik toegang heb http://localhost/foo/bar, Ik wil alleen /bar om het pad te zijn zoals ontvangen door de app. Dus ik heb geprobeerd deze regel toe te voegen aan het bovenstaande locatievak:

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

Dit veroorzaakt 302 redirect (verandering in URL), maar ik wil 301. Wat moet ik doen?


95
2018-04-15 17:31


oorsprong


Als je een probleem hebt met de Grafana-behuizing, moet je dit recept gebruiken: docs.grafana.org/installation/behind_proxy/... - mohsen saeedi


antwoorden:


Elke omleiding naar localhost is niet logisch van een systeem op afstand (zoals de webbrowser van de client). Dus de herschrijf vlaggen permanent (301) of redirect (302) kunnen in uw geval niet worden gebruikt.

Probeer de volgende instellingen te volgen met behulp van een transparante herschrijfregel:

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

Gebruik curl -i om je herschrijvingen te testen. Een zeer subtiele wijziging van de regel kan ervoor zorgen dat nginx een omleiding uitvoert.


117
2018-04-15 17:56



Het URL-pad begint nog steeds met / foo in mijn app wanneer ik dat doe ... - jeffreyveon
Er moet een ander probleem zijn. Ik heb dit scenario enkele minuten geleden met succes gereproduceerd. Oorspronkelijke URL: http: // ontwikkeling / foo / testme / 1234 - REQUEST_URI van een PHP-script dat wordt uitgevoerd op een Apache die is verbonden als proxy-back-end: '/ testme / 1234' - Jens Bradler
De regex zou waarschijnlijk moeten zijn /foo(.*), anders example.com/foo zal niet worden gekoppeld. (dat is waarschijnlijk wat jeffreyveon heeft meegemaakt) - Benno
Dit soort werken, maar mijn lichaam dat ik aan het instellen ben met proxy_set_body wordt verwijderd. - Justin Thomas
rewrite /(.*) /socket.io/ break; OPSLAAN MIJN DAG VOOR SOCKET.IO - user956584


Eenvoudige prefix-aanpassing van locaties werkt hiervoor zonder een herschrijfregel te gebruiken, zolang u een URI opgeeft in de proxy_pass-richtlijn:

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

Let op de extra / aan het einde van de proxy_pass richtlijn. NGINX verwijdert de overeenkomende prefix /foo en geef de rest door aan de backend-server op de URI /. daarom http://myserver:80/foo/bar zal posten naar de backend op http://localhost:3200/bar.

Van de NGINX-documenten op proxy_pass:

Als de proxy_pass-richtlijn is opgegeven met een URI, dan is er een   aanvraag wordt doorgegeven aan de server, het deel van een genormaliseerde aanvraag-URI   het matchen van de locatie wordt vervangen door een URI gespecificeerd in de richtlijn:


86
2017-09-29 03:30



Werkt voor mij dan ik heb toegevoegd / naar locatie / foo / { - Andrei N
Dit was precies wat ik zocht! - anbiniyar
Dit is een zeer schone oplossing, ik zou liever hebben dat dit het canonieke antwoord op de vraag is. - ralien
Het duurde te lang om te beseffen hoe belangrijk het is om slash te behouden of te verwijderen. - Parvez
Dit gaat echt over //xyz naar de gastheer als je dat doet. - Archimedes Trajano


De absoluut meest correcte manier en de beste werkwijze is meestal als volgt:

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

  • Let op het grote belang van de trailing slash in proxy_pass, die automatisch de $uri variabele om de /foo/ op de voorkant correspondeert met / op de backend. Geen behoefte aan een expliciete rewrite richtlijn.

  • Merk bovendien op dat de trailing / in de location is ook heel belangrijk - zonder dit riskeer je op een bepaald moment raar ogende URL's op je site te hebben (bijvoorbeeld een werkende /fooen in aanvulling op /foo/en).

    Bovendien, de achterstand / in de location met proxy_pass zorgt ook voor wat speciale behandeling, volgens de documentatie van de location richtlijn, om effectief een impliciete te veroorzaken location = /foo {return 301 /foo/;} ook.

    Dus, door het definiëren van een location met de volgende schuine streep zoals hierboven, zorgt u er niet alleen voor dat slash-less suffix-URL's zoals /fooen zal niet geldig zijn, maar ook dat een /foo zonder een trash slash blijft ook werken.


Referentiedocumentatie:


30
2017-08-26 21:12



Dit is het beste antwoord hier! - Mo Friedrich
Het lijkt op $args zijn verloren: http://frontend/foo?bar=baz zal worden ingediend bij http://backend/. Merk op dat args niet het deel van url zijn - Vanuan
@Vanuan, weet je dat zeker? Ik ben er vrij zeker van $args moet nog steeds op de juiste manier worden afgehandeld als u de bovenstaande code gebruikt, omdat deze niet in de lijst staan $uri, en moet weer worden teruggeplaatst, tenzij u expliciete variabelen in uw gebruikt proxy_pass. - cnst
@ArchimedesTrajano, je bent niet correct, omdat er speciale afhandeling voor is /foo omleiden naar /foo/, dus, tenzij je iets raars doet aan de achterkant, zelfs /foo verzoeken zullen nog steeds werken met de bovenstaande code. (Dit is eigenlijk al een deel van het antwoord, tussen haakjes.) - cnst
Dit is het beste antwoord! Dit moet omhoog komen. - phegde


proberen

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

of

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

0
2018-01-21 16:20



Dit antwoord zou goed zijn als je een verklaring geeft waarom het moet worden geconfigureerd zoals hierboven. - masegaloeh
Dit gaat echt over //xyz naar de gastheer als je dat doet. - Archimedes Trajano