Rimozione della barra finale da un URL con nginx


14

Vorrei che i seguenti URL sul mio sito fossero equivalenti:

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

e inoltre vorrei che i secondi due moduli emettessero reindirizzamenti HTTP 301 al primo modulo. Sto solo servendo pagine statiche, e sono organizzate secondo il terzo modulo. (In altre parole, quando un utente richiede /foo/bardi ricevere il file su /usr/share/.../foo/bar/index.html).

Il mio nginx.confcontiene attualmente quanto segue:

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

Questo funziona per le richieste di /foo/bar/index.html, ma quando chiedo /foo/baro /foo/bar/Safari mi dice che "si sono verificati troppi reindirizzamenti", suppongo che ci sia un ciclo di reindirizzamento infinito o qualcosa del genere. Come posso ottenere nginx per mappare gli URL ai file come ho descritto?

Modifica: la mia configurazione completa

Ecco il mio intero nginx.confcon il mio nome di dominio sostituito con "esempio.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;
    }
  }
}

Questi file esistono davvero sul filesystem?
Michael Hampton

@MichaelHampton Sì. Le richieste per /foo/bar/index.htmldevono restituire il file /usr/share/nginx/www/foo/bar/index.htmlo comunque è impostato. Tutti i percorsi sul sito Web corrispondono direttamente ai percorsi del file system.
bdesham,

@bdesham Non riesco a riprodurre. Ecco cosa ottengo con la tua configurazione paste.ubuntu.com/7501697
Alexey Ten,

@AlexeyTen È strano che tu stia ottenendo qualcosa di diverso. Grazie per averci dato un'occhiata. Ho pubblicato una configurazione che ha finito per funzionare per me.
bdesham,

Risposte:


19

Avere questa regex sul tuo serverblocco:

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

reindirizzerebbe tutti gli URL della barra finale alla rispettiva barra non finale.


1
Questo affronta solo una parte della domanda.
bdesham,

5
Questo affronta il titolo completo della domanda.
Jivan,

5

Sono stato in grado di ottenere il comportamento desiderato usando questo come serverblocco finale nella mia configurazione:

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

Questo non sembra funzionare per me: /index.htmlall'URL viene risposto HTTP 200 invece di un reindirizzamento; le righe "riscrivi" vengono ignorate. È ancora attuale?
Christoph Burschka,

1

Non usare mai la riscrittura:

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

Puoi espandere il motivo per cui non pensi che riscrivere sia una buona idea?
Bdesham,


Il motivo per cui i tuoi collegamenti suggeriscono di evitare riscritture è per la leggibilità implicita, non perché possono causare effetti collaterali indesiderati. La tua risposta è molto meno leggibile direwrite ^(.+)/+$ $1 permanent;
chrBrd

1
Questa è una buona risposta, non so perché sia ​​stata sottoposta a downgrade. L'articolo ha un titolo "Taxing Rewrites" che spiega perché rewritepuò essere negativo. Detto questo, la risposta fornita cattura e abbina anche l'URI, non sono sicuro che migliorerà le prestazioni, ha bisogno di essere testato. Utilizzare questa regex (?<no_slash>.+)/$invece di non reindirizzare la home page.
Rasoio

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

Questa regola si occuperà di qualsiasi numero di barre finali e manterrà l'URL. Si occuperà anche delle barre finali finali dell'URL di base

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.