nginx: убрать дубли страниц // /index.html /? (решение)

D
На сайте с 07.11.2000
Offline
219
1963

Почти все проекты имеют дубли вида (дубль -> правильный):

  • domen.com//dir// -> domen.com/dir/
  • domen.com/page? -> domen.com/page
  • domen.com/dir/index.html -> domen.com/dir/

Эти дубли есть практически во всех проектах: https://www.rambler.ru//, https://vk.com///feed и т.д.

Чтобы избежать дублей в индексе - можно прописать rel=canonical или просто сделать 301 редирект. Здесь я решил остановиться на 301 редиректе.

По слешам //: посмотрел примеры в инете - практически все они работают неверно. Отключают merge_slashes и цепочкой редиректят:

domen.com/dir///// -> domen.com/dir//// -> ... -> domen.com/dir/

#Плохое решение:
merge_slashes off;
rewrite (.*)//+(.*) $1/$2 permanent;

Изучил как работает merge_slashes.

merge_slashes on - это внутренне преобразование url для использования в локейшенах и правилах nginx. Это хорошо, и в большинстве случаев его и не нужно отключать.

Т.е. при merge_slashes on - урл domen.com/dir//// nginx видит как domen.com/dir/ и соответственно обрабатывает локейшены и отдает по адресу domen.com/dir//// содержимое domen.com/dir/ (повторюсь, внутри, т.е. редиректов не делает)

Чтобы не утомлять теорией - вот итог и краткие комментарии:

# вставляем в nginx.conf после location / (или другом нужном месте)

# этот блок удаляет ? и ?parameters из урл
if ($request_uri ~ \?) {
rewrite ^(.*)?(.*) $1? permanent;
}
# этот блок удаляет /index.html из урл
if ($request_uri ~ /index\.html$) {
rewrite ^(.*)index.html$ $1 permanent;
}

# этот блок удаляет все дубли // из урл за один раз
if ($request_uri ~ //) {
return 301 $uri;
}
# т.к. урл уже очищен nginx-ом при значении директивы merge_slashes on (по умолчанию)
# и чистый урл содержится в $uri - проверяем на наличие в адресе двух и более слешей //
# и просто делаем редирект на чистый урл
M
На сайте с 04.12.2013
Offline
223
#1

Все это лучше делать программно. Проблем с индексной страницей, особенно index.html, в современных движках обычно не возникает. В наших движках традиционного назначения в конфиг сервера выносится только работа с трэйлинг слешем (слешами), именем хоста и т.п. Естественно, и в конфиге сервера, и в движке делать редирект на каждый из множественных слешей – это тупость. С учетом написанного выше максимум будет двойной редирект, один при наличии трэйлинг слешей, другой при наличии всех прочих множественных слешей:

http://g09.ru/index.html/// - тут по идее должен сработать одиночный редирект, прописанный в конфиге сервера;

http://g09.ru///index.html - тут по идее должен сработать одиночный редирект, заложенный в фильтре движка;

http://g09.ru///index.html/// - и только тут может быть дв. редирект, если не прописать в конфиге сервера устранение всех множественных слешей, а не только трэйлинг.

Тут по идее должна быть 404-ая:

http://g09.ru/index.html?

Это связано с тем, что при отсутствии строки параметров, но наличии завершающего вопр. знака он считается частью завершающего слага. При необходимости редирект можно прописать программно в обработчике 404-ой, либо в обработчике для слага «index.html?».

Домены и скрипт для коротких ссылок: https://u75.ru/domains-for-shortcuts
D
На сайте с 07.11.2000
Offline
219
#2
miketomlin:
Все это лучше делать программно.

Не соглашусь.

Все это можно сделать на уровне быстрого nginx и не пускать на медленный бакэнд.

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий