Всё для сайтов

По выдержкам из RFC 1738 объяснены причины, согласно которым написание URL с оконечным слешем или без такого считается в обоих случаях правильным.

Полезные сведения

УРЛ со слешем или без - почему правильно именно так?

УРЛ со слешем или без - почему правильно именно так

Споры по этому вопросу - как правильно писать URL, со слешем на конце или без? - были и будут. Аргументация встречается разнообразная, и часто противоречива. А расплату за неверную запись универсального локатора ресурса (URL) воображают двух видов. Со стороны поисковиков - это якобы штрафные санкции за дубли страниц. С точки зрения производительности - якобы лишний редирект на страницу верной записи, автоматически генерируемый сервером.

Однако, разбирая технические спецификации стандартов Интернета, в частности документ " RFC 1738 - Uniform Resource Locators (URL)", приходится признать, что оба варианта записи адреса веб-ресурса формально правильные, и санкция за использование того или иного варианта - не более чем бзик поисковой системы или байки псевдо-SEO-шников.

С позиции лаконичности, более правильным представляется вариант без слеша на конце вне зависимости от того, адресует ли ваша ссылка "файл" на сервере или "папку", косвенное доказательство чему будет продемонстрировано ниже. Но и нет ни одного утверждения в документе, что иной вариант неверный или ссылается совсем на другой ресурс.

Загружать вас многостраничным переводом упомянутого RFC не стану, так как, во-первых, целью вопроса были слеши на конце URL, и во-вторых, публикация адресована простым пользователям движков, в том числе и Impera CMS, которым вся детализация не интересна, они ждут кратких разъяснений и доказательств по существу. Соответственно, я буду цитировать выдержки из сего документа в качестве доказательной базы и пояснять. Кому и это не интересно, может сразу смотреть вывод в конце статьи.

Общий синтаксис URL

Первым делом привлеку внимание к выдержке из параграфа 2. General URL Syntax (общий синтаксис URL). В каждом случае буду приводить фрагмент текста на языке оригинала и следом перевод на русский язык.

    URLs are used to `locate' resources, by providing an abstract
    identification of the resource location.
    URLы используются для 'нахождения' ресурсов, предоставляя
    абстрактное обозначение местоположения ресурса.

То есть сам URL - это чистая абстракция. Что он может показаться нам внешне похожим на имя файла или папки, вовсе не означает физическое указание на именно такой-то файл, а не какой-нибудь другой в файловом пространстве сервера. Ниже в документе об этом будет заявлено прямо.

Заметка Вообще в отношении http-ссылок в принципе неверно говорить, что например

  • http://domain.com/path/subpath/filename.txt - якобы указывает на файл
  • http://domain.com/path/subpath/ - якобы указывает на папку
  • http://domain.com/path - якобы неверно указывает на папку

Мы просто привыкли так говорить, потому что удобно ассоциировать ссылки с файлами на сайте. В действительности все эти ссылки указывают на некие ресурсы, никоим образом не обозначая тип ресурса. Что же скрывается за каждым ресурсом, то есть какой именно реальный файл или папка и какой тип контента будет отдан по такой ссылке, то уже определено конфигурацией сервера.

Важно уяснить, что в ссылках нет такого понятия как "файл", "папка", "подпапка", "текст", "картинка", "html", "скрипт", "таблица стилей" и так далее. Никакой слеш на конце или его отсутствие не значит ровным счётом ничего до тех пор, пока ссылка не пройдёт трансформацию внутри сервера, и уже он сам решит, куда же на самом деле указывает ссылка и какой контент какого типа скрывается за ней. Только это решение относится к внутренней архитектуре сервера.

Иерархические схемы

Далее выдержка из параграфа 2.3 Hierarchical schemes and relative links (иерархические схемы и относительные ссылки).

    Some URL schemes (such as the ftp, http, and file schemes) contain
    names that can be considered hierarchical; the components of the
    hierarchy are separated by "/".
    Некоторые схемы URL (такие как ftp, http и file) содержат имена,
    которые можно считать иерархическими; элементы иерархии
    разделены символом "/".

То есть утверждается, что в отдельных схемах адресов содержимое локатора ресурса не воспрещено подразумевать иерархическим, причём пока не оговаривалось, что иерархия эквивалентна какой-либо форме, скажем файловой.

Общий синтаксис сетевой схемы

Далее выдержка из параграфа 3.1. Common Internet Scheme Syntax (общий синтаксис сетевой схемы).

    //<user>:<password>@<host>:<port>/<url-path>

    Some or all of the parts "<user>:<password>@", ":<password>",
    ":<port>", and "/<url-path>" may be excluded.
    Некоторые или все части "<user>:<password>@", ":<password>",
    ":<port>" и "/<url-path>" можно исключать.

Заметка Это, кстати, ответ на вопрос, производный от рассматриваемого нами. Нередко и по такому вопросу спорят: как правильно давать ссылку на домен (хост) - без слеша в конце или со слешем?

Как правильно http://domain.com/ или http://domain.com ?

И так и так правильно. Просто первый слеш после имени хоста предназначен для отделения имени пути от имени хоста. Тот же параграф документа сообщает об этом так:

    url-path
        The rest of the locator consists of data specific to the
        scheme, and is known as the "url-path". It supplies the
        details of how the specified resource can be accessed. Note
        that the "/" between the host (or port) and the url-path is
        NOT part of the url-path.
        Остальная часть локатора состоит из данных, характерных
        для схемы, и известна как "url-path" (путь URL). Она сообщает
        подробности, как можно получить доступ к указанному ресурсу.
        Обратите внимание, что символ "/" между хостом (или портом)
        и путём URL - это не часть url-path.

Ни словом не обязали вас ставить этот замыкающий символ или не ставить, когда url-path равен пустой строке (как сказали бы многие из нас, когда URL ссылается в корень сайта). Никто не имеет права применить к вам штрафные санкции "за два дубля главной страницы", ибо согласно спецификации, в обоих случаях вы ссылаете URL на один и тот же ресурс.

Продолжим ещё одной выдержкой из того же параграфа.

    The url-path syntax depends on the scheme being used, as does the
    manner in which it is interpreted.
    Синтаксис url-path зависит от используемой схемы, как и
    способ, которым он интерпретируется.

Это лишнее подтверждение, что у каждой схемы локатора своё понятие "иерархии" и способ её интерпретации.

Иерархия

Далее выдержка из параграфа 3.2.4 Hierarchy (иерархия).

    For some file systems, the "/" used to denote the hierarchical
    structure of the URL corresponds to the delimiter used to construct a
    file name hierarchy, and thus, the filename will look similar to the
    URL path. This does NOT mean that the URL is a Unix filename.
    Символ "/" использован для обозначения иерархической структуры
    URL соответственно разделителю, используемому в конструировании
    иерархии файловых имён, и таким образом в некоторых файловых
    системах имя файла выглядит подобным пути URL. Но это не
    означает, что URL - это Unix-подобное имя файла.

Несмотря на то, что этот параграф относится к схеме ftp, тем не менее его утверждения распространимы и на другие схемы (http, gopher, prospero и так далее). Лишь в схеме file символ слеша логично обозначает то же, что и в именах файлов, например file://server_or_device/path/subpath/filename.txt.

Http

Далее выдержка из параграфа 3.3. HTTP.

    An HTTP URL takes the form:

        http://<host>:<port>/<path>?<searchpart>

    where <host> and <port> are as described in Section 3.1. If :<port>
    is omitted, the port defaults to 80.  No user name or password is
    allowed. <path> is an HTTP selector, and <searchpart> is a query
    string. The <path> is optional, as is the <searchpart> and its
    preceding "?". If neither <path> nor <searchpart> is present, the "/"
    may also be omitted.

    Within the <path> and <searchpart> components, "/", ";", "?" are
    reserved.  The "/" character may be used within HTTP to designate a
    hierarchical structure.
    URL схемы http принимает форму:

        http://<host>:<port>/<path>?<searchpart>

    где <host> и <port> такие же как описаны в параграфе 3.1.
    Если :<port> опущен, порт по умолчанию считается равным 80.
    Имя пользователя или пароль недопустимы. <path> - это
    селектор HTTP, и <searchpart> - строка запроса. <path> является
    опциональным, как и <searchpart> вместе с предшествующим
    ему символом "?". Если ни <path>, ни <searchpart> не присутствуют,
    символ "/" может также быть опущен.

    В элементах <path> и <searchpart> символы "/", ";", "?" являются
    зарезервированными. Символ "/" может использоваться в HTTP,
    чтобы определять иерархическую структуру.

Заметка Здесь также утверждается, что можно указывать ссылку без оконечного слеша. В данном случае речь шла о ситуации, когда путь ссылки пустой - указывает на корень хоста.

Формальная запись

И наконец выдержка из параграфа 5. BNF for specific URL schemes (формальная запись для конкретных схем URL).

Здесь в квадратных скобках указаны опциональные части. Звёздочка перед скобкой обозначает 0 или более повторов такого фрагмента, как указан в скобках. Вертикальную черту следует понимать как ИЛИ.

hostport    = host [ ":" port ]
...
...

httpurl     = "http://" hostport [ "/" hpath [ "?" search ]]
hpath       = hsegment *[ "/" hsegment ]
hsegment    = *[ uchar | ";" | ":" | "@" | "&" | "=" ]
search      = *[ uchar | ";" | ":" | "@" | "&" | "=" ]

...
...

lowalpha    = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" |
              "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" |
              "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" |
              "y" | "z"
hialpha     = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
              "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
              "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"

alpha       = lowalpha | hialpha
digit       = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
              "8" | "9"
safe        = "$" | "-" | "_" | "." | "+"
extra       = "!" | "*" | "'" | "(" | ")" | ","

hex         = digit | "A" | "B" | "C" | "D" | "E" | "F" |
              "a" | "b" | "c" | "d" | "e" | "f"
escape      = "%" hex hex

unreserved  = alpha | digit | safe | extra
uchar       = unreserved | escape

Обратите внимание, как точно по правилам формируется элемент hpath - путь ссылки. Элементы hsegment пути - сегменты - разделяются слешем. Словно намекая на важную идею, что слеш делит путь на иерархические части и всегда находится внутри. В принципе не исключается, что последний элемент hsegment может являться пустой строкой (это следует из его определения), и тогда на конце URL невольно появляется закрывающий слеш.

Вывод

Деление пути на сегменты с помощью символа слеша подразумевает наличие непустых имён этих сегментов. Соответственно, ссылка со слешем на конце видится нелогичной (хотя и не воспрещена) в том смысле, что она вроде бы указывает на некий последний сегмент пути, но притом никак не называет этот сегмент. Точно так как нелогична (но тоже не воспрещена) ссылка http://domain.com/level1////levelX, не называющая промежуточные сегменты пути, если путь рассматривать не как набор параметров, а как иерархическую структуру.

Просторечным языком смысловое наполнение двух ссылок можно пояснить так:

  • http://domain.com/level1/level2   - адресует в дефолтную начальную точку второго уровня иерархии
  • http://domain.com/level1/level2/   - адресует в неопределённую точку внутри второго уровня иерархии, то есть как бы на сервер возлагают задачу, что "мы обращаемся ко второму уровню иерархии, а ты сам определи, какую точку считаешь в этом уровне дефолтной начальной".

Несмотря на оконечный слеш во второй ссылке, она всё же адресует во второй уровень иерархии, а не в третий, потому что ссылка явно не назвала имя третьего уровня.

Из всего сказанного выше следует, что аналогично тому, как ссылки

  • http://domain.com
  • http://domain.com/

адресуют посетителя в корень сайта, так и например ссылки

  • http://domain.com/level1/level2
  • http://domain.com/level1/level2/

адресуют посетителя во второй уровень иерархии ресурса. А то что некий сервер может интерпретировать слеш на конце по-своему и начать внутренне редиректить на дефолтную начальную точку уровня - скажем на файл index.html, это уже частный случай конкретной конфигурации. Точно так как и в реализации системы человеко-понятных URL все записи редиректов с помощью серверного модуля mod_rewrite определяют своё (присущее конкретному движку) понятие иерархического строения URL, в котором элементы пути могут приравниваться к параметрам запроса и вовсе не иметь общего с файловой структурой сайта (классический пример: http://domain.com/ru/path, элемент ru - это параметр текущего языка, а не папка на сайте).

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

К сведению

На уровне реализации вопрос слешей на концах не имеет принципиального значения, чему множество подтверждений среди именитых порталов. На одних все ссылки завершают слешем, на других - без слеша. Главное чтобы контент по ссылкам не оказывался разным, и ещё для Яндекса нужно прописать 301-й редирект с тех ссылок, которыми вы не пользуетесь (скажем оканчивающихся слешем), на те, которыми пользуетесь. Дело в том, что по неподтверждённым утверждениям службы поддержки Яндекса, этот поисковик якобы может ошибаться и не "склеивать" (запоминать в своих знаниях) или с некоторым запозданием склеивать слеш-без-слешевые адреса в один.

Ответ службы поддержки Яндекс

Вот пример реализации такого редиректа с помощью корневого файла .htaccess:

# если входной url оканчивается слеш(ем, ами),
# задаём 301-й редирект на страницу без слеша

RewriteCond  %{REQUEST_URI}  ^/.+/$
RewriteRule  ^(.*?)/+$       http://%{HTTP_HOST}/$1  [R=301,L,QSA]

Гуглу (опять же по сведениям, не подтверждённым экспериментом) эти редиректы не важны, так как он будто бы умеет склеивать такие адреса правильно и без редиректов.

Помните Есть немало людей, считающих себя SEO-специалистами. Но не каждый из них таким является. Более того, темой SEO часто спекулируют без должных знаний и оснований, просто в расчёте на то, что и вы неосведомлены в этой области, поэтому легко поверите в любую "лапшу". Когда вам говорят, что какая-то ваша страница "вылетела из индекса", воспользуйтесь очень хорошей рекомендацией Яндекса: Узнавать об ошибках индексирования, если таковые возникают, можно в сервисе Яндекс.Вебмастер. В этом сервисе всегда можно увидеть список ваших страниц, находящихся в поиске и список страниц, по какой-то причине исключённых из поиска. Похожий сервис есть и у Гугла. Доверяйте этим знаниям, а не мнению псевдо-специалистов, которые где-то что-то краем уха слышали, и на том основании рекомендуют вам делать так, как им кажется единственно правильным.

Обсуждение
«Сергей | 6 мар 20:44
Ну хоть один показал доказательства. Сколько я блин нерва попортил, переделывая все ссылки чтобы закрывались слешем. Мой сеошник сказал надо так.
Ответить
«Анатолий | 6 мар 22:36
Чтож это у вас сеошник специалист такой, если ссылки правили вы. Этим как раз должен был заниматься он.
Ответить
«Андрей | 25 апр 19:14
То что надо! Спасибо!!! Решил проблему!!!
Ответить
«Polina | 2 июн 12:08
Спасибо, очень полезная статья!
Ответить
«Юрий | 17 сен 12:16
Согласен со всем!
У меня все ссылки отправляются в основной файл index.php на сервере который находиться соответственно в корне сайта, а он уже обрабатывает вложенность урл и формирует контент согласно вложенности. По сути то таких файлов и папок вовсе нет на сервере.

И таки да, проблема не в урл а в формировании контента. Если по адресу "mysite.ru/bla-bla-bla/" формируется такой же контент как и по адресу "mysite.ru/bla-bla-bla" могут быть проблемы и все же лучше от них подстраховаться выбрав какой то один из вариантов подправив файл htaccess.

По поводу склейки данных урл, специально сегодня прочитав вашу статью, думаю дай гляну в гугл веб мастер. И таки опять да... он все склеил. НО БУКВАЛЬНО ПОЛ ГОДА НАЗАД БЫЛИ ДУБЛИ! Так что разговор об этом имеет место быть.
Ответить
«Макс | 11 янв 11:00
Спасибо. Всё понятно написано. Остался вопрос. Нужно ли продублировать заголовки редиректов в head страницы или достаточно htacces? Чтобы склейка прошла быстрее.
Ответить
«Matroskin | 17 янв 16:17
Поисковый бот смотрит серверные заголовки. Head это из другой сказки. Поэтому только htaccess.
Ответить
«Евгений | 12 фев 08:36
Вот это объяснение - со ссылкой на правила. А не пустые разглагольствования, как у многих. Спасибо.
Ответить

Другие обсуждения »

Теги: схемы url, url, url schemes

Хотите чтобы мы рассказали ещё о чём-то - предлагайте тему.

Предложить

Следите за нашими публикациями в социальных сетях и новостных каналах.