การลบเครื่องหมายสแลชต่อท้ายออกจาก URL ด้วย nginx


14

ฉันต้องการให้ URL ต่อไปนี้ในเว็บไซต์ของฉันเท่ากัน:

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

และต่อไปฉันต้องการให้สองรูปแบบที่สองเพื่อออก HTTP 301 redirects ไปยังแบบฟอร์มแรก ฉันแค่ให้บริการหน้าคงที่และพวกเขาจะจัดเรียงตามรูปแบบที่สาม (กล่าวอีกนัยหนึ่งเมื่อผู้ใช้ร้องขอ/foo/barพวกเขาควรได้รับไฟล์ที่/usr/share/.../foo/bar/index.html)

nginx.confปัจจุบันของฉันมีดังต่อไปนี้:

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

สิ่งนี้ใช้ได้กับคำขอ/foo/bar/index.htmlแต่เมื่อฉันร้องขอ/foo/barหรือ/foo/bar/Safari บอกฉันว่า“ เกิดการเปลี่ยนเส้นทางมากเกินไป” - ฉันถือว่ามีลูปการเปลี่ยนเส้นทางที่ไม่สิ้นสุดหรืออะไรทำนองนั้น ฉันจะรับ nginx เพื่อจับคู่ URL กับไฟล์ในแบบที่ฉันอธิบายได้อย่างไร

แก้ไข: การกำหนดค่าเต็มของฉัน

นี่คือทั้งหมดของฉันnginx.confด้วยชื่อโดเมนของฉันแทนที่ด้วย“ 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;
    }
  }
}

ไฟล์เหล่านี้มีอยู่จริงในระบบไฟล์หรือไม่?
Michael Hampton

@MichaelHampton ใช่ คำร้องขอ/foo/bar/index.htmlควรส่งคืนไฟล์ที่/usr/share/nginx/www/foo/bar/index.htmlหรือตั้งค่าไว้ เส้นทางทั้งหมดในเว็บไซต์ตรงกับเส้นทางของระบบไฟล์โดยตรง
bdesham

@bdesham ฉันไม่สามารถทำซ้ำได้ นี่คือสิ่งที่ฉันจะได้รับจาก config วางของคุณUbuntu.com/7501697
Alexey Ten

@AlexeyTen มันแปลกที่คุณจะได้รับสิ่งที่แตกต่าง ขอบคุณที่มองมัน ฉันโพสต์การกำหนดค่าที่สิ้นสุดการทำงานสำหรับฉัน
bdesham

คำตอบ:


19

มี regex นี้ในserverบล็อกของคุณ:

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

จะเปลี่ยนเส้นทาง URL สแลชต่อท้ายทั้งหมดไปยังสแลชต่อท้ายที่ไม่เกี่ยวข้อง


1
ที่อยู่นี้เป็นเพียงส่วนหนึ่งของคำถาม
bdesham

5
ที่อยู่นี้เป็นชื่อเต็มของคำถาม
Jivan

5

ฉันสามารถรับพฤติกรรมที่ต้องการโดยใช้สิ่งนี้เป็นserverบล็อกสุดท้ายในการกำหนดค่าของฉัน:

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

ดูเหมือนจะใช้งานไม่ได้สำหรับฉัน - /index.htmlตอบ URL ด้วย HTTP 200 แทนการเปลี่ยนเส้นทาง บรรทัด "rewrite" จะถูกละเว้น ปัจจุบันนี้ยังคงอยู่หรือไม่?
Christoph Burschka

1

อย่าใช้การเขียนซ้ำ:

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

คุณสามารถขยายความว่าทำไมคุณไม่คิดว่าการเขียนใหม่เป็นความคิดที่ดีหรือไม่?
bdesham


เหตุผลที่ลิงก์ของคุณแนะนำให้หลีกเลี่ยงการเขียนซ้ำนั้นมีไว้สำหรับความชัดเจนในการอ่านไม่ใช่เพราะอาจทำให้เกิดผลข้างเคียงโดยไม่ได้ตั้งใจ คำตอบของคุณอ่านได้น้อยกว่าrewrite ^(.+)/+$ $1 permanent;
chrBrd

1
นี่เป็นคำตอบที่ดีฉันไม่รู้ว่าทำไม downvote บทความมีหัวข้อ "การเขียนซ้ำภาษี" ที่อธิบายว่าทำไมจึงrewriteไม่ดี ที่กล่าวไปแล้วคำตอบที่ให้นั้นยังจับภาพและจับคู่ URI ได้ฉันไม่แน่ใจว่าจะปรับปรุงประสิทธิภาพหรือไม่นั้นจำเป็นต้องมีการทดสอบ ใช้ regex นี้(?<no_slash>.+)/$แทนเพื่อไม่เปลี่ยนเส้นทางโฮมเพจ
มีดโกน

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

กฎนี้จะดูแลสแลชต่อท้ายจำนวนเท่าใดก็ได้และจะเก็บ URL ไว้ นอกจากนี้ยังจะดูแลเครื่องหมายทับต่อท้าย URL พื้นฐาน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.