Nginx и двойные слэши в урл

Всем привет!

Такой вопрос тем, кто пользуется 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
Алексей Карташов
26 декабря 2013, 23:34
modx.pro
3
13 898
0

Комментарии: 8

Виталий Киреев
27 декабря 2013, 06:37
0
Проверил, в самой адресной строке не убирает, но и отображает правильно, как будто там 1 слеш. И по мне так проблема надуманная.
    Алексей Карташов
    27 декабря 2013, 06:54
    0
    Отлично, значит это не у меня проблема и всё сделал правильно. Спасибо!

    И по мне так проблема надуманная.
    Ок, дайте мне ссылку на какой-нибудь статичный html-сайт, который есть в топах по вкусным запросам — я его мигом оттуда выкину :-)

    И да, такие сайты есть. И есть они потому, что делались давно и со временем начали занимать хорошие позиции в поиске.
    Не обновляют их по простой причине — чтобы позиции не попортить, «а то мало ли...» :-)
      Виталий Киреев
      27 декабря 2013, 06:56
      0
      Вроде как поисковики наоборот любят, когда контент на странице часто обновляется)
        Алексей Карташов
        27 декабря 2013, 06:59
        0
        Тематика и топы бывают разные. Погуглите «консервированные топы в яндексе». Увидите как много возмущений оптимизаторов на эту тему (в основном, конечно, на сёрче много обсуждений).
          Виталий Киреев
          27 декабря 2013, 07:01
          0
          Подозреваю все просто проплачено :) По такому запросу мне выдает только про консервированные арбузы))) наверно учитывает «мои предпочтения»)))
            Алексей Карташов
            27 декабря 2013, 07:03
            0
            Эээ, покажите куда платить! Я продам квартиру и через 2 месяца буду жить в 3х этажном доме!)
              Алексей Карташов
              27 декабря 2013, 07:32
              0
              Да, согласен, не удачный пример для гугления)) Мне он тоже выдаёт про консервы))

              Вот периодически читаю форум серча и очень часто обсуждают то, что «молодняку» невозможно пробиться, а топы «законсервированы». Но вот через поиск хотя бы одной подобной темы найти так и не получилось. Ананасы да арбузы)
      Cyrax_02
      24 октября 2016, 01:40
      1
      0
      Да, при [merge_slashes = on] nginx удаляет слеши из uri, но только на внутреннем уровне — без внешних (301) редиректов.

      Вариант, работающий только при [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;
      }
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        8