Назад | Перейти на главную страницу

Nginx перезаписывает все html файлы, кроме индекса

У меня проблемы с перезаписью Nginx. Недавно я перешел в блоге на новый движок, и структура URL-адресов изменилась. В моем старом движке для ведения блогов сообщения располагались по URL-адресу с формой http://$host/yyyy/mm/title.html однако на новом движке они имеют вид http://$host/yyyy/mm/title/. Фактический файл, возвращаемый сервером, находится в /yyyy/mm/title/index.html.

Чтобы убедиться, что ссылки в старых сообщениях по-прежнему работают, я хочу переписать в Nginx примерно так:

rewrite ^/(\d\d\d\d)/(\d\d)/(.+)\.html$ $scheme://$host/$1/$2/$3/ permanent;

К сожалению, это ловит все, что заканчивается на .html включая index.html, поэтому посещение URL-адреса формы /(\d\d\d\d/)/(\d\d)/(.+)/ вызывает цикл перенаправления (nginx внутренне пытается использовать /$1/$2/$3/index.html, который перенаправляет на /$1/$2/$3/, который перенаправляет обратно на index.html и т. д.).

Я бы предпочел не использовать операторы if, если это вообще возможно. Любые идеи?

Для справки, сайт статический, а конфигурация моего сервера выглядит примерно так (здесь ничего особенного):

server {
  listen      [::]:80;
  server_name blog.samwhited.com;
  root /var/www/blog.samwhited.com;
  charset utf-8;
  location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires max;
    log_not_found off;
  }
  error_page 404 /error/404.html;
  error_page 403 /error/403.html;
  location /error/ { internal; }
}

Вот краткий пример ожидаемого поведения перенаправления:

http://blog.samwhited.com/2008/09/test.html -> http://blog.samwhited.com/2008/08/test/

Также было бы здорово, если бы index.html можно было скрыть. Ничего из того, что я нашел в Интернете, не помогло. Так что это тоже сработает:

http://blog.samwhited.com/2008/09/test/index.html -> http://blog.samwhited.com/2008/09/test/

Вам в значительной степени нужно использовать if заявление, но это совершенно безопасно, если у вас есть только rewrite директивы внутри него. Вы хотите проверить $uri переменная, поскольку она включает модификации, сделанные index модуль.

if ($uri !~ /index\.html$) {
    rewrite ^/test/(\d\d\d\d)/(\d\d)/(.+)\.html$ /$1/$2/$3/ permanent;
}

Чтобы удалить index.html часть вам нужно отправить редирект, но только если клиент указан index.html, и это не было добавлено index модуль. Значит, нам нужен еще один if заявление, чтобы проверить это. Мы используем $request_uri здесь переменная, которую клиент фактически отправил.

if ($request_uri ~ /index\.html($|\?)) {
    rewrite ^(.*)/index\.html$ $1/ permanent;
}