Menghapus garis miring dari URL dengan nginx

14

Saya ingin agar URL berikut di situs saya setara:

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

dan selanjutnya saya ingin dua bentuk kedua untuk mengeluarkan pengalihan HTTP 301 ke bentuk pertama. Saya hanya melayani halaman statis, dan mereka diatur sesuai dengan bentuk ketiga. (Dengan kata lain, ketika pengguna meminta /foo/barmereka harus menerima file di /usr/share/.../foo/bar/index.html).

nginx.confSaat ini saya berisi yang berikut:

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

Ini berfungsi untuk permintaan /foo/bar/index.html, tetapi ketika saya meminta /foo/baratau /foo/bar/Safari memberi tahu saya bahwa "terlalu banyak pengalihan terjadi" - saya berasumsi ada loop pengalihan tak terbatas atau sesuatu seperti itu. Bagaimana saya bisa mendapatkan nginx untuk memetakan URL ke file dengan cara yang saya jelaskan?

Sunting: Konfigurasi lengkap saya

Ini seluruh saya nginx.confdengan nama domain saya diganti dengan "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
sumber
Apakah file-file ini benar-benar ada di sistem file?
Michael Hampton
@MichaelHampton Ya. Permintaan /foo/bar/index.htmlharus mengembalikan file pada /usr/share/nginx/www/foo/bar/index.htmlatau bagaimanapun itu sudah diatur. Semua jalur di situs web berhubungan langsung dengan jalur sistem file.
bdesham
@bdesham saya tidak bisa mereproduksi. Inilah yang saya dapatkan dengan config paste.ubuntu.com/7501697
Alexey Ten
@AlexeyTen Aneh bahwa Anda mendapatkan sesuatu yang berbeda. Terima kasih telah memeriksanya. Saya telah memposting konfigurasi yang akhirnya berfungsi untuk saya.
bdesham

Jawaban:

19

Memiliki regex ini di serverblok Anda :

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

akan mengarahkan semua URL garis miring ke masing-masing garis miring non.

Francisco Costa
sumber
1
Ini hanya menjawab sebagian dari pertanyaan.
bdesham
5
Ini membahas judul lengkap pertanyaan.
Jivan
5

Saya bisa mendapatkan perilaku yang saya inginkan dengan menggunakan ini sebagai serverblok terakhir dalam konfigurasi saya:

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
sumber
Ini sepertinya tidak berfungsi untuk saya - /index.htmlURL dijawab dengan HTTP 200 alih-alih redirect; baris "tulis ulang" diabaikan. Apakah ini masih terkini?
Christoph Burschka
1

Jangan pernah gunakan menulis ulang:

  location ~ (?<no_slash>.*)/$ {
       return 301 $scheme://$host$no_slash;
  }
Eldar Agalarov
sumber
Bisakah Anda mengembangkan alasan mengapa Anda tidak berpikir menulis ulang adalah ide yang bagus?
bdesham
Alasan tautan Anda menyarankan untuk menghindari penulisan ulang adalah karena keterbacaan yang tertunda, bukan karena dapat menyebabkan efek samping yang tidak diinginkan. Jawaban Anda jauh lebih mudah dibaca daripadarewrite ^(.+)/+$ $1 permanent;
chrBrd
1
Ini adalah jawaban yang bagus, saya tidak tahu mengapa itu diturunkan. Artikel itu memiliki tajuk "Taxing Rewrites" yang menjelaskan mengapa rewritebisa buruk. Itu dikatakan, jawaban yang diberikan juga menangkap dan cocok dengan URI, saya tidak yakin apakah akan meningkatkan kinerja, perlu pengujian. Gunakan regex ini (?<no_slash>.+)/$sebagai gantinya untuk tidak mengarahkan halaman beranda.
Razor
0
if ($request_uri ~ (.*?\/)(\/+)$ ) {
return 301 $scheme://$host$1;
}

Aturan ini akan menangani sejumlah garis miring dan akan mempertahankan URL. Ini juga akan menangani pemotongan garis dasar URL

Ashish Amre
sumber