Eliminar la barra diagonal final de una URL con nginx

14

Me gustaría que las siguientes URL en mi sitio fueran equivalentes:

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

Además, me gustaría que los dos segundos formularios emitan redireccionamientos HTTP 301 al primer formulario. Solo estoy sirviendo páginas estáticas, y están organizadas de acuerdo con el tercer formulario. (En otras palabras, cuando un usuario solicita /foo/bardebe recibir el archivo en /usr/share/.../foo/bar/index.html).

Mi nginx.confactualmente contiene lo siguiente:

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

Esto funciona para solicitudes /foo/bar/index.html, pero cuando solicito /foo/baro /foo/bar/Safari me dice que "se produjeron demasiados redireccionamientos", supongo que hay un bucle de redireccionamiento infinito o algo así. ¿Cómo puedo hacer que nginx asigne URL a archivos de la manera que he descrito?

Editar: mi configuración completa

Aquí está mi todo nginx.confcon mi nombre de dominio reemplazado con "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;
    }
  }
}
Bdesham
fuente
¿Existen realmente estos archivos en el sistema de archivos?
Michael Hampton
@MichaelHampton Sí. Las solicitudes de /foo/bar/index.htmldeben devolver el archivo en /usr/share/nginx/www/foo/bar/index.htmlo como esté configurado. Todas las rutas en el sitio web corresponden directamente a las rutas del sistema de archivos.
bdesham
@ Bdesham No puedo reproducir. Aquí lo que obtengo con su configuración paste.ubuntu.com/7501697
Alexey Ten
@AlexeyTen Es extraño que estés obteniendo algo diferente. Gracias por investigarlo. He publicado una configuración que terminó funcionando para mí.
bdesham

Respuestas:

19

Tener esta expresión regular en tu serverbloque:

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

redirigiría todas las URL de barra diagonal final a la barra diagonal secundaria respectiva.

Francisco Costa
fuente
1
Esto aborda solo una parte de la pregunta.
bdesham
55
Esto aborda el título completo de la pregunta.
Jivan
5

Pude obtener mi comportamiento deseado al usar esto como el serverbloque final en mi configuración:

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;
  }
}
Bdesham
fuente
Esto no parece funcionar para mí: la /index.htmlURL se responde con HTTP 200 en lugar de una redirección; las líneas de "reescritura" se ignoran. ¿Sigue siendo actual?
Christoph Burschka
1

Nunca use reescribir:

  location ~ (?<no_slash>.*)/$ {
       return 301 $scheme://$host$no_slash;
  }
Eldar Agalarov
fuente
¿Puedes explicar por qué no crees que reescribir es una buena idea?
bdesham el
La razón por la cual sus enlaces sugieren evitar reescrituras es por una legibilidad mejorada, no porque puedan causar efectos secundarios no deseados. Su respuesta es mucho menos legible querewrite ^(.+)/+$ $1 permanent;
chrBrd
1
Esta es una buena respuesta, no sé por qué se ha rechazado. El artículo tiene un encabezado "Reescritura de impuestos" que explica por qué rewritepuede ser malo. Dicho esto, la respuesta proporcionada también captura y coincide con el URI, no estoy seguro de si mejorará el rendimiento, necesita pruebas. Utilice esta expresión regular en su (?<no_slash>.+)/$lugar para no redirigir la página de inicio.
Navaja
0
if ($request_uri ~ (.*?\/)(\/+)$ ) {
return 301 $scheme://$host$1;
}

Esta regla se encargará de cualquier número de barras finales y retendrá la URL. También se ocupará de las barras diagonales finales de URL base

Ashish Amre
fuente