У меня проблемы с перезаписью 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;
}