- PVSM.RU - https://www.pvsm.ru -

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

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

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

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

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

Первым делом привлеку внимание к выдержке из параграфа 2. General URL Syntax [3] (общий синтаксис 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   —   якобы неверно указывает на папку

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

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

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

    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 [5] (общий синтаксис сетевой схемы).

    //<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 [6] (иерархия).

    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, тем не менее его утверждения распространимы и на другие схемы.

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

    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 [8] (формальная запись для конкретных схем 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
  • http://domain.com/

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

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

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

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

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

Автор: ImperaCMS

Источник [9]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/cms/44851

Ссылки в тексте:

[1] RFC 1738: http://tools.ietf.org/html/rfc1738

[2] моего: http://imperacms.ru/

[3] 2. General URL Syntax: http://tools.ietf.org/html/rfc1738#section-2

[4] 2.3 Hierarchical schemes and relative links: http://tools.ietf.org/html/rfc1738#section-2.3

[5] 3.1. Common Internet Scheme Syntax: http://tools.ietf.org/html/rfc1738#section-3.1

[6] 3.2.4 Hierarchy: http://tools.ietf.org/html/rfc1738#section-3.2.4

[7] 3.3. HTTP: http://tools.ietf.org/html/rfc1738#section-3.3

[8] 5. BNF for specific URL schemes: http://tools.ietf.org/html/rfc1738#section-5

[9] Источник: http://habrahabr.ru/post/196186/