URL с несколькими косыми чертами, это что-нибудь ломает?

http://example.com/something/somewhere//somehow/script.js

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

8 ответов

Решение

HTTP RFC 2396 определяет разделитель пути как одиночную косую черту.

Однако, если вы не используете какой-либо вид перезаписи URL (в этом случае на правила перезаписи может влиять количество слешей), URI отображается на путь на диске, но в (большинстве?) Современных операционных системах (Linux / Unix, Windows), несколько разделителей пути в строке не имеют какого-либо специального значения, поэтому / path / to / foo и / path // to //// foo в конечном итоге отобразятся в одном и том же файле.

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

Правильный ответ на этот вопрос зависит от реализации сервера!

Предисловие: Двойная косая черта является синтаксически допустимой в соответствии с RFC 2396, который определяет синтаксис пути URL. Как объясняет amn, следовательно, он подразумевает пустой сегмент URI. Однако обратите внимание, что RFC 2396 определяет только синтаксис, а не семантику путей, включая пустые сегменты пути, поэтому ваш сервер должен решить семантику пустого пути.

Вы не упомянули, какой стек программного обеспечения вы используете, возможно, вы даже используете свой собственный? Поэтому, пожалуйста, используйте свое воображение относительно того, какой может быть семантика!

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

  1. Поскольку пустое значение является действительным, как-то не ожидается всеми, это может вызвать ошибки. И хотя ваша серверная технология сегодня может быть совместима с ней, либо ваша серверная технология завтрашнего дня, либо следующая версия вашей серверной технологии сегодня может решить не поддерживать ее больше. Пример: библиотека ASP.NET MVC Web API выдает ошибку при попытке указать шаблон маршрута с двойной косой чертой.

  2. Некоторые серверы могут интерпретировать // как указание корневого пути. Это может быть либо намеренная ошибка, либо ошибка, и, скорее всего, это ошибка безопасности, то есть уязвимость, связанная с обходом каталога.

  3. Поскольку это иногда ошибка и ошибка безопасности, некоторые умные серверные стеки и брандмауэры будут видеть подстроку "//", что вы можете сделать попытку использования такой ошибки, и поэтому они вернутся 403 Forbidden или же 400 Bad Request и т.д., и отказаться от какой-либо дальнейшей обработки URI.

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

Рассмотрим декларацию соответствующего path-absolute нетерминальный в "RFC3986: унифицированный идентификатор ресурса (URI): общий синтаксис" (указан, как обычно, в синтаксисе ABNF):

path-absolute = "/" [ segment-nz *( "/" segment ) ]

Затем рассмотрим segment объявите несколько строк ниже в том же документе:

segment       = *pchar

Если вы можете прочитать ABNF, звездочка (*) указывает, что следующий элемент pchar может повторяться несколько раз, чтобы составить segmentв том числе ноль раз. Изучение этого и перечитывание path-absolute Объявление выше, вы можете увидеть, что потенциально пустой segment подразумевает, что второй "/" может повторяться бесконечно, следовательно, допускаются допустимые комбинации, такие как ////// (произвольная длина не менее одного /) как часть path-absolute (который сам по себе используется при указании правила, описывающего URI).

Поскольку все URL-адреса являются URI, мы можем сделать вывод, что да, URL-адреса допускаются несколько последовательных прямых слешей, согласно указанному RFC.

Но не все следуют или реализуют парсеры URI в соответствии со спецификацией, поэтому я вполне уверен, что существуют несовместимые парсеры URI/URL и все виды программного обеспечения, которые устанавливаются поверх них, когда такие угловые случаи ломают большие системы.

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

URL с таким же путем, повторенный 3 раза, не будет проиндексирован в Google

Пример, который они используют:

example.com/path/path/path/

Я не подтвердил, что это также будет правдой, если вы использовали example.com///, но я бы определенно хотел выяснить, была ли оптимизация SEO критической для моего сайта.

Они упоминают, что "это потому, что Google считает, что попал в ловушку URL". Если кто-то знает ответ наверняка, добавьте комментарий к этому ответу; в противном случае я счел целесообразным включить это дело в рассмотрение.

Да, это может определенно сломать вещи.

Спецификация считает http://host/pages/foo.html а также http://host/pages//foo.html быть разными URI, и серверы могут назначать им разные значения. Однако большинство серверов будут обрабатывать пути /pages/foo.html а также /pages//foo.html идентично (потому что основная файловая система тоже). Но даже когда имеешь дело с такими серверами, дополнительная косая черта легко может сломать вещи. Рассмотрим ситуацию, когда сервер возвращает относительный URI.

http://host/pages/foo.html  + ../images/foo.png = http://host/images/foo.png
http://host/pages//foo.html + ../images/foo.png = http://host/pages/images/foo.png

Позвольте мне объяснить, что это значит. Скажем, ваш сервер возвращает HTML-документ, который содержит следующее:

<img src="../images/foo.png">

Если ваш браузер получил эту страницу, используя

http://host/pages/foo.html          # Path has 2 segments: "pages" and "foo.html"

Ваш браузер попытается загрузить

http://host/images/foo.png          # ok

Однако, если ваш браузер получил эту страницу, используя

http://host/pages//foo.html         # Path has 3 segments: "pages", "" and "foo.html"

вы, вероятно, получите ту же страницу (потому что сервер, вероятно, не различает /pages//foo.html от /pages/foo.html), но ваш браузер по ошибке попытается загрузить

http://host/pages/images/foo.png    # XXX

Вы можете быть удивлены, например, при создании ссылок для ресурсов в вашем приложении.

<script src="mysite.com/resources/jquery//../angular/script.js"></script>

не разрешит mysite.com/resources/angular/script.js но mysite.com/resources/jquery/angular/script.js что вы, вероятно, не хотели

Двойная косая черта зла, старайтесь избегать их.

Ваш вопрос "это что-нибудь сломает". С точки зрения спецификации URL допускаются дополнительные косые черты. Не читайте RFC, вот быстрый эксперимент, который вы можете попытаться увидеть, если ваш браузер молча меняет URL:

echo '<?= $_SERVER['REQUEST_URI'];' > tmp.php                                   
php -S localhost:4000 tmp.php

Я протестировал macOS 10.14 (18A391) с Safari 12.0 (14606.1.36.1.9) и Chrome 69.0.3497.100, и оба получили результат:

/Привет, мир

Это указывало на то, что использование дополнительной косой черты является видимым для веб-приложения.

Некоторые варианты использования будут нарушены при использовании двойной косой черты. Это включает в себя перенаправления / маршрутизацию URL-адресов, которые ожидают однослойный URL-адрес, или другие приложения CGI, которые непосредственно анализируют URI.

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

Другие вопросы по тегам