Nginx veroorzaakt 301-omleiding als er geen slash is

Ik gebruik nginx op een virtuele machine met NAT en ik heb omleidingsproblemen wanneer ik het vanaf de hostmachine benader.

Werkt zoals verwacht

  • http://localhost:8080/test/index.htm: werkt.
  • http://localhost:8080/test/: werkt.

Werkt niet zoals verwacht

  • http://localhost:8080/test: verwijst door naar http://localhost/test/. Dit is nietwat ik wil. (merk op dat het poortnummer wordt verwijderd)

Wat ik heb geprobeerd

Op basis van wat ik heb gegoogled, heb ik geprobeerd server_name_in_redirect off;en rewrite ^([^.]*[^/])$ $1/ permanent;, beide zonder succes.

Mijn standaard.conf:

server {
    listen       80;
    server_name  localhost;
    # server_name_in_redirect off;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm index.php;
    }
    location ~ \.php$ {
    # rewrite ^([^.]*[^/])$ $1/ permanent;
        root           /usr/share/nginx/html;
        try_files      $uri =404;
        #fastcgi_pass   127.0.0.1:9000;
        fastcgi_pass   unix:/tmp/php5-fpm.sock;
        fastcgi_index  index.php;
        include        fastcgi_params;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

Antwoord 1, autoriteit 100%

Ik heb een mogelijke oplossing voor dit probleem gepost op serverfault; voor het gemak hier gereproduceerd:

Als ik de vraag goed begrijp, wil je automatisch, zonder een 301-omleiding, http:/ /example.com/foo/index.htmlwanneer het verzoek is voor http://example.com/foozonder slash?

Basisoplossing die voor mij werkt

Zo ja, ik heb geconstateerd dat deze try_files-configuratie werkt:

try_files $uri $uri/index.html $uri/ =404;
  • De eerste $urikomt exact overeen met de uri
  • De tweede $uri/index.htmlkomt overeen met een map die de index.html bevat, waarbij het laatste element van het pad overeenkomt met de map
    naam, zonder slash
  • De derde $uri/komt overeen met de directory
  • De vierde =404retourneert de 404-foutpagina als geen van de voorgaande patronen overeenkomt.

Overgenomen van Serverfault-antwoord

Mijn bijgewerkte versie

Als u het server-blok toevoegt:

index index.html index.htm;

En pas try_filesaan om er als volgt uit te zien:

try_files $uri $uri/ =404;

Het zou ook moeten werken.


Antwoord 2, autoriteit 75%

Een wat eenvoudigere oplossing, die voor mij werkte, is om absolute omleidingen uit te schakelen met absolute_redirect off;zoals in het volgende voorbeeld:

server {
    listen 80;
    server_name  localhost;
    absolute_redirect off;
    location /foo/ {
        proxy_pass http://bar/;
    }

Als ik curl op http://localhost:8080/foouitvoer, kan ik zien dat de Location-header in de HTTP-reactie voor omleiding wordt gegeven als /foo/en niet http://localhost/foo/.

$ curl -I http://localhost:8080/foo
HTTP/1.1 301 Moved Permanently
Server: nginx/1.13.8
Date: Tue, 03 Apr 2018 20:13:28 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: /foo/

Daaruit neem ik aan dat elke webbrowser het juiste zou doen met de relatieve locatie. Getest in Chrome en het werkt prima.


Antwoord 3, autoriteit 30%

probeer:

server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm index.php;
        if (-d $request_filename) {
            rewrite [^/]$ $scheme://$http_host$uri/ permanent;
        }
    }
}

Antwoord 4, autoriteit 12%

Probeer te veranderen

server_name  localhost;
# server_name_in_redirect off;

naar

server_name  localhost:8080;
server_name_in_redirect on;

Other episodes