Nginx и двойные слэши в урл
Всем привет!
Такой вопрос тем, кто пользуется nginx.
У всех он (nginx) удаляет повторяющиеся слэши из урла? Именно nginx, как веб-сервер, а не modx! MODX с успехом (301) такие урлы исправляет, если они ему попадаются.
Т.е. если вбить адрес:
Вот начитался я доков по nginx'у, гуглил, читал SO, и везде пишут, что nginx должен делать это автоматом, благодаря директиве merge_slashes, которая включена по умолчанию.
И абсолютно везде указывают на неё.
Но у меня она не работает. Вообще и никак.
Чтобы фокус удался, мне пришлось в контексте http {/*...*/} выключить merge_slashes:
Проблемы с двойными слешами бы не было, если бы nginx отдавал 404 на такие адреса, но он успешно показывает нужную страницу, будь в урле хоть десяток слэшей. А это дубликаты для поисковиков и простор для творчества конкурентов в выдаче.
Поэтому вот такой выход. Но правильно ли это? Может я что-то делаю не так?
Версия nginx — 1.2.1
Такой вопрос тем, кто пользуется nginx.
У всех он (nginx) удаляет повторяющиеся слэши из урла? Именно nginx, как веб-сервер, а не modx! MODX с успехом (301) такие урлы исправляет, если они ему попадаются.
Т.е. если вбить адрес:
http://domain.tld///folder////nested-folder///page.html
на сайте, на котором не установлен modx (например html-статика), превращаются ли у вас дублирующие слэши в одинарные:http://domain.tld/folder/nested-folder/page.html
?Вот начитался я доков по nginx'у, гуглил, читал SO, и везде пишут, что nginx должен делать это автоматом, благодаря директиве merge_slashes, которая включена по умолчанию.
И абсолютно везде указывают на неё.
Но у меня она не работает. Вообще и никак.
Чтобы фокус удался, мне пришлось в контексте http {/*...*/} выключить merge_slashes:
merge_slashes off;
, а уже на уровне контекста server {/*...*/} вручную делать преобразование:location ~* .*//+.* {
rewrite (.*)//+(.*) $1/$2 permanent;
}
Вот только после всё работает.Проблемы с двойными слешами бы не было, если бы nginx отдавал 404 на такие адреса, но он успешно показывает нужную страницу, будь в урле хоть десяток слэшей. А это дубликаты для поисковиков и простор для творчества конкурентов в выдаче.
Поэтому вот такой выход. Но правильно ли это? Может я что-то делаю не так?
Версия nginx — 1.2.1
Комментарии: 8
Проверил, в самой адресной строке не убирает, но и отображает правильно, как будто там 1 слеш. И по мне так проблема надуманная.
Отлично, значит это не у меня проблема и всё сделал правильно. Спасибо!
И да, такие сайты есть. И есть они потому, что делались давно и со временем начали занимать хорошие позиции в поиске.
Не обновляют их по простой причине — чтобы позиции не попортить, «а то мало ли...» :-)
И по мне так проблема надуманная.Ок, дайте мне ссылку на какой-нибудь статичный html-сайт, который есть в топах по вкусным запросам — я его мигом оттуда выкину :-)
И да, такие сайты есть. И есть они потому, что делались давно и со временем начали занимать хорошие позиции в поиске.
Не обновляют их по простой причине — чтобы позиции не попортить, «а то мало ли...» :-)
Вроде как поисковики наоборот любят, когда контент на странице часто обновляется)
Тематика и топы бывают разные. Погуглите «консервированные топы в яндексе». Увидите как много возмущений оптимизаторов на эту тему (в основном, конечно, на сёрче много обсуждений).
Подозреваю все просто проплачено :) По такому запросу мне выдает только про консервированные арбузы))) наверно учитывает «мои предпочтения»)))
Эээ, покажите куда платить! Я продам квартиру и через 2 месяца буду жить в 3х этажном доме!)
Да, согласен, не удачный пример для гугления)) Мне он тоже выдаёт про консервы))
Вот периодически читаю форум серча и очень часто обсуждают то, что «молодняку» невозможно пробиться, а топы «законсервированы». Но вот через поиск хотя бы одной подобной темы найти так и не получилось. Ананасы да арбузы)
Вот периодически читаю форум серча и очень часто обсуждают то, что «молодняку» невозможно пробиться, а топы «законсервированы». Но вот через поиск хотя бы одной подобной темы найти так и не получилось. Ананасы да арбузы)
Да, при [merge_slashes = on] nginx удаляет слеши из uri, но только на внутреннем уровне — без внешних (301) редиректов.
Вариант, работающий только при [merge_slashes = off]
Конструкция, которую вы привели, имеет логическую ошибку, из-за чего удалять она будет только по одному слешу (если подряд идущих слешей — несколько, будет несколько последовательных 301 редиректов), что не есть хорошо. В rewrite первая звёздочка захватит часть слешей, оставив конструкции //+ только 2 слеша.
Что нужно сделать, чтобы довести конструкцию до ума:
1. «Умерить» жадность этой звёздочки
2. Добавить символы начала и конца строки (не обязательно, но желательно)
3. Максимально упростить регулярное выражение в location (т.к. оно используется только для обнаружения факта присутствия в uri лишних слешей)
Вариант, работающий только при [merge_slashes = on]
А ещё лучше использовать конструкцию, которая не требует отключения merge_slashes (работает только при включенном merge_slashes):
Универсальный вариант, не зависящий от состояния [merge_slashes]
Если же нужен универсальный вариант, который не зависит от состояния директивы merge_slashes, то делаем так (слэши в составе аргументов не трогаем):
Вариант, работающий только при [merge_slashes = off]
Конструкция, которую вы привели, имеет логическую ошибку, из-за чего удалять она будет только по одному слешу (если подряд идущих слешей — несколько, будет несколько последовательных 301 редиректов), что не есть хорошо. В rewrite первая звёздочка захватит часть слешей, оставив конструкции //+ только 2 слеша.
Что нужно сделать, чтобы довести конструкцию до ума:
1. «Умерить» жадность этой звёздочки
2. Добавить символы начала и конца строки (не обязательно, но желательно)
3. Максимально упростить регулярное выражение в location (т.к. оно используется только для обнаружения факта присутствия в uri лишних слешей)
location ~ // {
rewrite ^(.*?)//+(.*)$ $1/$2 permanent;
}
Вариант, работающий только при [merge_slashes = on]
А ещё лучше использовать конструкцию, которая не требует отключения merge_slashes (работает только при включенном merge_slashes):
if ($request_uri ~ ^[^?]*//) {
rewrite ^ $uri permanent;
}
Здесь переменная $request_uri содержит исходный uri с исходными аргументами запроса (до корректировки веб-сервером и до всяких внутренних редиректов). Конструкция ^[^?]* слева от слешей нужна, чтобы убедиться, что лишние слеши обнаружены именно в uri, а не в составе аргументов (слэши в составе аргументов не трогаем). И в самую последнюю очередь делаем 301 редирект на uri, который nginx уже самостоятельно очистил от лишних слешей (это значение содержится в переменной $uri).Универсальный вариант, не зависящий от состояния [merge_slashes]
Если же нужен универсальный вариант, который не зависит от состояния директивы merge_slashes, то делаем так (слэши в составе аргументов не трогаем):
if ($request_uri ~ ^(?P<left>[^?]*?)//+(?P<right>[^?]*)) {
rewrite ^ $left/$right permanent;
}
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.