Добавьте косую черту в конец каждого URL-адреса (требуется правило перезаписи для nginx)

Я стараюсь ставить "/" в конец каждого URL:

example.com/art

должен

example.com/art/

Я использую nginx в качестве веб-сервера.

Для этого мне нужно правило перезаписи ..

Для лучшего понимания проверьте это:

http://3much.schnickschnack.info/art/projekte

Если вы нажмете на маленькую миниатюру под большой картинкой, она перезагрузится и покажет этот URL:

http://3much.schnickschnack.info/art/projekte/#0

Если у меня теперь есть косая черта на всех URL-адресах (в конце), это будет работать без перезагрузки сайта.

Прямо сейчас у меня есть эти настройки в nginx-http.conf:

server {
  listen *:80;
  server_name 3much.schnickschnack.info;
  access_log /data/plone/deamon/var/log/main-plone-access.log;
  rewrite ^/(.*)$ /VirtualHostBase/http/3much.schnickschnack.info:80/2much/VirtualHostRoot/$1 last;
  location / {
    proxy_pass http://cache;
  }
}

Как мне настроить nginx на добавление косой черты? (Я думаю, мне следует переписать правило?)


person Gomez    schedule 14.03.2009    source источник
comment
Эм ... зачем вам нужен / в конце всех ваших URL?   -  person cletus    schedule 14.03.2009
comment
Мне это нужно для галереи js. Если нет / перезагружает сайт ...   -  person Gomez    schedule 14.03.2009
comment
Мне нужно правило перезаписи для nginx ....   -  person Gomez    schedule 14.03.2009
comment
Итак, вопрос в том, как мне настроить nginx для добавления косой черты? Или это Как мне настроить nginx для работы без косой черты?   -  person S.Lott    schedule 14.03.2009
comment
Вопрос должен: Как мне настроить nginx на добавление косой черты?   -  person Gomez    schedule 15.03.2009


Ответы (9)


Скорее, я думаю, вам нужно что-то вроде этого:

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

Регулярное выражение переводится как «перезаписать все URI без каких-либо символов». в них, которые не заканчиваются на '/' в URI + '/' "Или просто:" Если URI не имеет точки и не заканчивается косой чертой, добавьте косую черту в конец "

Причина перезаписи URI только без точек в них заключается в том, что любой файл с расширением файла не перезаписывается. Например, ваши изображения, css, javascript и т. Д. И предотвращение возможных циклов перенаправления при использовании некоторой PHP-структуры, которая также выполняет свои собственные перезаписи.

Еще одна распространенная перезапись, сопровождающая это:

rewrite ^([^.]*)$ /index.php;

Это очень просто перезаписывает все URI, в которых нет точек, в ваш index.php (или любой другой файл, из которого вы выполняете свой контроллер).

person Bob Monteverde    schedule 12.10.2010
comment
Это единственный пост в сети, который не добавляет косую черту ко ВСЕМ. спасибо за публикацию. - person ansiart; 20.10.2011
comment
этот работает намного более надежно, особенно с фреймворками php, которые имеют собственное переписывание ссылок - person anthonysomerset; 13.01.2012
comment
У меня есть статические файлы html, так что domain.com/about получает файл < b> domain.com/about.html, но по-прежнему показывает URL без .html. Я хочу добавить косую черту после того, как ударил по файлу, но сейчас получаю 404, если я добавлю косую черту. Поэтому я хочу удалить завершающую косую черту (если она существует), и с конечной косой чертой или без нее получает файл -html, но показывает / после. Это не работает: rewrite ^/([a-zA-Z0-9]+)$ /$1.html; rewrite ^([^.]*[^/])$ $1/ permanent; Также, если несколько раз щелкнуть примерно в меню, я получаю этот домен .com / about / about / about и т. д. - person Asle; 09.01.2017
comment
А как насчет строк запроса? - person Benubird; 15.11.2017
comment
@EtienneMartin Похоже, он перепишет domain.com/page?thing=abc в domain.com/page?thing=abc/. Или nginx определяет и обрабатывает строки запроса отдельно? - person Benubird; 04.01.2019
comment
@Benubird Да, я подумал то же самое, когда увидел это, но он проверил это, и похоже, что строки запроса обрабатываются отдельно. - person Etienne Martin; 04.01.2019
comment
Я мог делать что-то здесь не так, но, к сожалению, это не работает при работе с вложенными каталогами. У меня нет nginx, поэтому я просто тестирую его на regex101.com, поэтому удаляю условие начала строки, чтобы работают с полным URL http://example.com/foo/bar, шаблон [^.]*[^/]$ соответствует com/foo/bar. \/\w+[^.][^/]$, с другой стороны, соответствует /bar, но не /bar.html или /bar/ - person hyperwiser; 13.11.2019
comment
К сожалению, это не работает, если URL-адрес содержит порт: localhost: 8080 / something превращается в localhost / something: T - person Efrain; 27.05.2021

rewrite ^([^.\?]*[^/])$ $1/ permanent;

чтобы избежать добавления тега / в строку запроса URL-адреса отдыха.

e.g.

/ myrest / do? d = 12345

person Marc    schedule 19.05.2013
comment
как вы могли сделать результат `` / myrest / do /? d = 12345 '' - person Patrick Lee Scott; 08.04.2016
comment
@PatrickLeeScott Добавление "?" для регулярного выражения для исключения было бы достаточно, я думаю - person Satish Patro; 29.05.2021

Для nginx:

rewrite ^(.*[^/])$ $1/ permanent;
person bryan    schedule 25.09.2010
comment
Это добавит косую черту ко ВСЕМУ - так что вы получите index.php - ›index.php / и page? A = b -› page? A = b / где OP, безусловно, хочет page? A = b - ›page /? a = b - person Benubird; 15.11.2017

Странно, что это первый результат в Google, но на него нет удовлетворительного ответа. Я знаю два хороших способа сделать это. Первый - это прямая проверка, попадет ли запрос в файл, и применить условие перезаписи только в противном случае. Например.

server {
   # ...
   if (!-f $request_filename) {
     rewrite [^/]$ $uri/ permanent;
   }
   location / {
      # CMS logic, e.g. try_files $uri $uri /index.php$request_uri;
   }
   # ...
}

Второй, который многие предпочитают, поскольку они предпочли бы избегать любого использования if, которое не является 100% необходимым, - это использовать try_files для отправки запроса в именованный блок местоположения, когда он не сработает файл. Например.

server {
   # ...
   location / {
      try_files $uri $uri/ @cms;
   }
   location @cms {
      rewrite [^/]$ $uri/ permanent;
      # CMS logic, e.g. rewrite ^ /index.php$request_uri;
   }
   # ...
}
person Andrew Dinmore    schedule 12.12.2016

уже слишком поздно, но я хочу поделиться своим решением, я столкнулся с проблемой с завершающей косой чертой и nginx.

#case : 
# 1. abc.com/xyz  => abc.com/xyz/
# 2. abc.com/xyz/ => abc.com/xyz/
# 3. abc.com/xyz?123&how=towork => abc.com/xyz/?123&how=towork
# 4. abc.com/xyz/?123&ho=towork => abc.com/xyz/?123&how=towork

и это мое решение

server { 
    ....
    # check if request isn't static file
    if ($request_filename !~* .(gif|html|jpe?g|png|json|ico|js|css|flv|swf|pdf|xml)$ ) {
       rewrite (^[^?]+[^/?])([^/]*)$ $1/$2 permanent;
    }
    ....
    location / {
    ....
    }
}
person Kai    schedule 01.02.2016
comment
Мне очень нравится твое решение. Мне помогло :). Его также можно улучшить с помощью более универсального регулярного выражения для сопоставления файлов: if ($request_filename !~* .[a-zA-Z0-9]+$ ) Это должно соответствовать любому файлу. - person Andreas Hauschild; 24.05.2021

Используя перезаписи из anthonysomerset в Wordpress, я экспериментировал с проблемами доступа к панели инструментов / wp-admin из-за цикла переадресации. Но я решаю эту проблему, используя указанное выше условие:

if ($request_uri !~ "^/wp-admin")
{
rewrite ^([^.]*[^/])$ $1/ permanent;
rewrite ^([^.]*)$ /index.php;
}
person Ernesto Gámez    schedule 12.03.2014

server {
    # ... omissis ...

    # put this before your locations
    rewrite ^(/.*[^/])$ $1/ permanent;

    # ... omissis ...
}

Если вы хотите, чтобы какие-то запросы (скажем, кроме GET) не могли выполнять это (обычно это касается POST запросов, поскольку rewrite превращает любой метод запроса в GET, что может нарушить некоторые динамические функции вашего сайта), добавьте if пункт:

server {
    # ... omissis ...

    # put this before your locations
    if ($request_method = "GET" ) {
        rewrite ^(/.*[^/])$ $1/ permanent;
    }

    # ... omissis ...
}

Вы также можете поместить rewrite в блок location (if тоже), чтобы сделать его более конкретным.

person Dmitri Sologoubenko    schedule 24.07.2015

Если nginx находится за прокси с https, этот фрагмент выполняет правильное перенаправление для $scheme

map $http_x_forwarded_proto $upstream_scheme {
    "https" "https";
    default "http";
}

server {
    ...
    location / {
        rewrite ^([^.\?]*[^/])$ $upstream_scheme://$http_host$1/ permanent;
    }
    ...
}

И на восходящем прокси-сервере передайте заголовок X-Forwarded-Proto, например:

location / {
    proxy_set_header X-Forwarded-Proto $scheme;
    ...
}
person METAJIJI    schedule 16.03.2018

Попробуйте это: ^(.*)$ http://domain.com/$1/ [L,R=301]

Это перенаправляет (код состояния 301) все ($ 1) без "/" на "$ 1 /"

person Mork0075    schedule 14.03.2009
comment
Гомес: Вы должны абсолютно 301 (перенаправить) URL без косой черты на URL с косой чертой, иначе поисковые системы будут видеть example.com/blah и example.com/blah/ как две полностью отдельные страницы. - person dbr; 14.03.2009
comment
Я только что это проверил. ^ (. *) $ перенаправляет все независимо. Вместо этого мне пришлось использовать ^ (. *) [^ /], Поэтому он выполняет перенаправление только в том случае, если нет конечной косой черты. - person Chris; 12.08.2009
comment
Этот ответ, по-видимому, предоставляет синтаксис для Apache, но исходный вопрос касается nginx. - person bryan; 25.09.2010