Entfernen des abschließenden Schrägstrichs aus einer URL mit nginx


13

Ich möchte, dass die folgenden URLs auf meiner Website gleichwertig sind:

/foo/bar
/foo/bar/
/foo/bar/index.html

und außerdem möchte ich, dass die zweiten beiden Formulare HTTP 301-Weiterleitungen zum ersten Formular ausgeben. Ich bediene nur statische Seiten, und sie sind nach der dritten Form angeordnet. (Mit anderen Worten, wenn ein Benutzer dies wünscht /foo/bar, sollte er die Datei unter erhalten /usr/share/.../foo/bar/index.html).

Mein nginx.confenthält derzeit Folgendes:

rewrite ^(.+)/$ $1 permanent;
index index.html;
try_files $uri $uri/index.html =404;

Dies funktioniert für Anfragen nach /foo/bar/index.html, aber wenn ich anfordere /foo/baroder /foo/bar/Safari mir mitteilt, dass "zu viele Weiterleitungen aufgetreten sind", gehe ich davon aus, dass es eine Endlosumleitungsschleife oder ähnliches gibt. Wie kann ich nginx dazu bringen, URLs wie beschrieben zu Dateien zuzuordnen?

Bearbeiten: Meine vollständige Konfiguration

Hier ist mein gesamtes nginx.confmit meinem Domainnamen ersetzt durch "example.com".

user www-data;
worker_processes 1;
pid /run/nginx.pid;

events {
  worker_connections 768;
}

http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 65;
  types_hash_max_size 2048;
  server_tokens off;

  server_names_hash_bucket_size 64;

  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;

  gzip on;
  gzip_disable "msie6";
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss application/atom+xml text/javascript image/svg+xml;

  server {
    server_name www.example.com;
    listen 80;
    return 301 $scheme://example.com$request_uri;
  }

  server {
    server_name example.com 123.45.67.89 localhost;
    listen 80 default_server;

    # Redirect /foobar/ to /foobar
    rewrite ^(.+)/$ $1 permanent;

    root /usr/share/nginx/www/example.com;
    index index.html;
    try_files $uri $uri/index.html =404;

    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;

    location = /50x.html {
      root /usr/share/nginx/html;
    }
  }
}

Sind diese Dateien tatsächlich im Dateisystem vorhanden?
Michael Hampton

@ MichaelHampton Ja. Anfragen für /foo/bar/index.htmlsollten die Datei an zurückgeben /usr/share/nginx/www/foo/bar/index.htmloder wie auch immer sie eingerichtet ist. Alle Pfade auf der Website entsprechen direkt den Dateisystempfaden.
Bdesham

@bdesham Ich kann nicht reproduzieren. Hier, was ich mit Ihrer Konfiguration paste.ubuntu.com/7501697
Alexey Ten

@AlexeyTen Es ist seltsam, dass Sie etwas anderes bekommen. Vielen Dank, dass Sie sich damit befasst haben. Ich habe eine Konfiguration veröffentlicht, die für mich funktioniert hat.
Bdesham

Antworten:


19

Mit diesem regulären Ausdruck in Ihrem serverBlock:

rewrite ^/(.*)/$ /$1 permanent;

würde alle URLs mit abschließenden Schrägstrichen auf den jeweiligen nicht abschließenden Schrägstrich umleiten.


1
Dies betrifft nur einen Teil der Frage.
Bdesham

4
Hier wird der vollständige Titel der Frage angesprochen.
Jivan

5

Ich konnte mein gewünschtes Verhalten erreichen, indem ich dies als letzten serverBlock in meiner Konfiguration verwendete:

server {
  server_name example.com 123.45.67.89 localhost;
  listen 80 default_server;

  # Redirect /foobar/ and /foobar/index.html to /foobar
  rewrite ^(.+)/+$ $1 permanent;
  rewrite ^(.+)/index.html$ $1 permanent;

  root /usr/share/nginx/www/example.com;
  index index.html;
  try_files $uri $uri/index.html =404;

  error_page 404 /404.html;
  error_page 500 502 503 504 /50x.html;

  location = /50x.html {
    root /usr/share/nginx/html;
  }
}

Dies scheint bei mir nicht zu funktionieren - die /index.htmlURL wird mit HTTP 200 anstelle einer Umleitung beantwortet. Die Zeilen zum "Umschreiben" werden ignoriert. Ist das noch aktuell?
Christoph Burschka

0

Verwenden Sie niemals das Umschreiben:

  location ~ (?<no_slash>.*)/$ {
       return 301 $scheme://$host$no_slash;
  }

Können Sie erläutern, warum Sie das Umschreiben nicht für eine gute Idee halten?
Bdesham

Lesen Sie den Nginx-
Eldar Agalarov

Der Grund, warum Ihre Links vorschlagen, Umschreibungen zu vermeiden, liegt in der schlechten Lesbarkeit, nicht darin, dass sie unbeabsichtigte Nebenwirkungen verursachen können. Ihre Antwort ist weit weniger lesbar alsrewrite ^(.+)/+$ $1 permanent;
chrBrd

1
Dies ist eine gute Antwort, ich weiß nicht, warum es abgelehnt wurde. Der Artikel hat eine Überschrift "Taxing Rewrites", die erklärt, warum rewriteschlecht sein kann. Das heißt, die bereitgestellte Antwort erfasst und stimmt auch mit dem URI überein. Ich bin nicht sicher, ob dies die Leistung verbessern wird. Es muss getestet werden. Verwenden Sie (?<no_slash>.+)/$stattdessen diesen regulären Ausdruck , um die Startseite nicht umzuleiten.
Rasiermesser

0
if ($request_uri ~ (.*?\/)(\/+)$ ) {
return 301 $scheme://$host$1;
}

Diese Regel berücksichtigt eine beliebige Anzahl von abschließenden Schrägstrichen und behält die URL bei. Es wird sich auch um nachgestellte Schrägstriche der Basis-URL kümmern

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.