web-dev-qa-db-fra.com

Suppression de la barre oblique finale d'une URL avec nginx

Je voudrais que les URL suivantes sur mon site soient équivalentes:

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

et en outre, je voudrais que les deux seconds formulaires émettent des redirections HTTP 301 vers le premier formulaire. Je ne sers que des pages statiques, et elles sont organisées selon le troisième formulaire. (En d'autres termes, lorsqu'un utilisateur demande /foo/bar ils devraient recevoir le fichier à /usr/share/.../foo/bar/index.html).

Ma nginx.conf contient actuellement les éléments suivants:

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

Cela fonctionne pour les demandes de /foo/bar/index.html, mais quand je demande /foo/bar ou /foo/bar/ Safari me dit que "trop ​​de redirections se sont produites" - je suppose qu'il y a une boucle de redirection infinie ou quelque chose comme ça. Comment puis-je demander à nginx de mapper des URL à des fichiers de la manière que j'ai décrite?

Edit: Ma configuration complète

Voici tout mon nginx.conf avec mon nom de domaine remplacé par "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;
    }
  }
}
14
bdesham

J'ai pu obtenir le comportement souhaité en l'utilisant comme dernier bloc server dans ma configuration:

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;
  }
}
5
bdesham

Avoir cette expression régulière sur votre bloc server:

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

redirigerait toutes les URL de barre oblique de fin vers la barre oblique non de fin respective.

19
Francisco Costa

N'utilisez jamais la réécriture:

  location ~ (?<no_slash>.*)/$ {
       return 301 $scheme://$Host$no_slash;
  }
1
Eldar Agalarov
if ($request_uri ~ (.*?\/)(\/+)$ ) {
return 301 $scheme://$Host$1;
}

Cette règle prendra en charge n'importe quel nombre de barres obliques de fin et conservera l'URL. Il prendra également en charge les barres obliques de fin des URL de base

0
Ashish Amre