
Споры по этому вопросу - как правильно писать URL, со слешем на конце или без? - были и будут. Аргументация встречается разнообразная, и часто противоречива. А расплату за неверную запись универсального локатора ресурса (URL) воображают двух видов. Со стороны поисковиков - это якобы штрафные санкции за дубли страниц. С точки зрения производительности - якобы лишний редирект на страницу верной записи, автоматически генерируемый сервером.
Однако, разбирая технические спецификации стандартов Интернета, в частности документ " RFC 1738 - Uniform Resource Locators (URL)", приходится признать, что оба варианта записи адреса веб-ресурса формально правильные, и санкция за использование того или иного варианта - не более чем бзик поисковой системы или байки псевдо-SEO-шников.
С позиции лаконичности, более правильным представляется вариант "без слеша на конце" вне зависимости от того, адресует ли ваша ссылка "файл" на сервере или "папку", косвенное доказательство чему будет продемонстрировано ниже. Но и нет ни одного утверждения в документе, что иной вариант неверный или ссылается совсем на другой ресурс.
Загружать вас многостраничным переводом упомянутого RFC не стану, так как, во-первых, целью вопроса были слеши на конце 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.
Далее выдержка из параграфа 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 часто спекулируют без должных знаний и оснований, просто в расчёте на то, что и вы неосведомлены в этой области, поэтому легко поверите в любую "лапшу". Когда вам говорят, что какая-то ваша страница "вылетела из индекса", воспользуйтесь очень хорошей рекомендацией Яндекса: Узнавать об ошибках индексирования, если таковые возникают, можно в сервисе Яндекс.Вебмастер. В этом сервисе всегда можно увидеть список ваших страниц, находящихся в поиске и список страниц, по какой-то причине исключённых из поиска. Похожий сервис есть и у Гугла. Доверяйте этим знаниям, а не мнению псевдо-специалистов, которые где-то что-то краем уха слышали, и на том основании рекомендуют вам делать так, как им кажется единственно правильным.
Автор:
Impera CMS, 2 октября 2013 года