ОК, чтобы пропустить косую черту перед строкой запроса? - PullRequest
56 голосов
/ 24 октября 2009

Безопасно ли всегда пропускать косую черту при добавлении строки запроса?

То есть я могу использовать

http://example.com?querystring

вместо:

http://example.com/?querystring

? Все веб-хосты, которые я использовал, поддерживают это, но можно ли предположить, что все серверные среды будут поддерживать этот метод? Это стандарт?

Ответы [ 4 ]

49 голосов
/ 13 февраля 2017

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

Хотя принятый ответ правильно цитирует RFC 1738 (выпущенный более 20 лет назад!), Он ошибочно утверждает, что RFC 2396 (выпущенный в 1998 г.) требует косой черты, и игнорирует, что оба из этих спецификаций в RFC 3986 , выпущенный в 2005 году (еще за несколько лет до того, как был принят принятый ответ), а совсем недавно - Стандарт URL-адресов WhatWG , оба из которых позволяют использовать косую черту опущено.

Давайте рассмотрим каждую из этих спецификаций по очереди, от самой ранней до последней:


RFC 1738: унифицированные указатели ресурсов (URL) (выпущено в 1994 г.)

Неявно требуется, чтобы косая черта была включена , указывая, что она может быть опущена , если URL не содержит ни пути, ни строки запроса (называемой searchpart, здесь). Выделение внизу мое:

HTTP-URL принимает форму:

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

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


RFC 2396: унифицированные идентификаторы ресурсов (URI): общий синтаксис (выпущен в 1998 году; «обновляет» RFC 1738)

Здесь допустимо опускать косую черту. Этот RFC узаконивает некоторые странные синтаксисы URL, которые не имеют двойной косой черты после схемы, но если мы игнорируем их (это те, которые opaque_part в спецификации BNF ) и придерживаются URL, которые содержат хост, тогда мы находим, что absoluteURI определяется следующим образом ...

absoluteURI   = scheme ":" ( hier_part | opaque_part )

и что hier_part выглядит так:

hier_part     = ( net_path | abs_path ) [ "?" query ]

и что net_path выглядит так:

net_path      = "//" authority [ abs_path ]

, где abs_path, в свою очередь, определено, чтобы начинаться с косой черты. Обратите внимание, что abs_path является необязательным в грамматике выше - это означает, что URL-адрес формы scheme://authority?query является полностью допустимым.

Мотивация для этого изменения указана в приложении G.2. Модификации из RFC 1738 и RFC 1808 :

Знак вопроса "?" персонаж был удален из набора разрешенных символы для userinfo в компоненте полномочий, начиная с тестирования показал, что многие приложения рассматривают его как зарезервированный для разделения Компонент запроса от остальной части URI.

Другими словами - код в реальном мире предполагал, что первый знак вопроса в URL, где угодно, помечает начало строки запроса, и поэтому спецификация была прагматически обновлена ​​в соответствии с реальностью.


RFC 3986: унифицированный идентификатор ресурса (URI): общий синтаксис (выпущен в 2005 г .; «устарел» RFC 2396)

Опять же, допустимо опускать косую черту. Спецификация выражает это, говоря, что «путь» требуется в каждом URI, который содержит полномочия (хост), и этот путь должен или начинаться с косой черты или , состоящей из символов :

3. Синтаксические компоненты

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

URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

hier-part   = "//" authority path-abempty
            / path-absolute
            / path-rootless
            / path-empty

Требуются компоненты схемы и пути, хотя путь может быть пусто (без символов). Когда авторитет присутствует, путь должен либо быть пустым, либо начинаться с символа косой черты ("/").

Для полноты обратите внимание, что path-abempty определено позже так:

path-abempty  = *( "/" segment )

Это действительно позволяет ему не содержать символов.


URL Standard от WhatWG (уровень жизни при активном обслуживании, впервые созданный в 2012 году с целью устаревания RFC 3986)

Опять же, пропуск косой черты допустим, хотя на этот раз у нас нет БНФ, но вместо этого нам нужно читать много прозы.

Раздел 4.3 говорит нам:

Строка absolute-URL должна быть одной из следующих

любой необязательно сопровождается "?" и строка URL-запроса.

Поскольку HTTP и HTTPS являются специальными схемами , любой URL-адрес HTTP или HTTPS должен удовлетворять первому из этих трех параметров, то есть http: или https:, за которым следует относительно схемы -special-URL строка , которая:

должно быть "//", за которым следует допустимая строка хоста , за которой необязательно следуют ":" и строка URL-порта , за которыми следует путь-абсолютный-URL-строка .

A строка path-absolute-URL определена, чтобы начинаться с косой черты, но явно необязательна в определении строки абсолютного URL выше; таким образом, допустимо переходить от хоста прямо к «?» и строке запроса, поэтому URL-адреса, такие как http://example.com?query, являются допустимыми.


Конечно, ничто из этого не дает чёткой гарантии того, что каждый веб-сервер или HTTP-библиотека будет принимать такие URL-адреса и что они будут обрабатывать их как семантически эквивалентные URL-адресу, который содержит косую черту. Но что касается spec , пропуск косой черты вполне законен.

46 голосов
/ 24 октября 2009

Нет. Неправильно пропускать косую черту. Это может работать в современных браузерах: однако это не делает его правильным.

См. RFC1738 - URL и RFC2396 - URI .

Формат в соответствии с RFC1738 (здесь я исключил формат схемы):

// @ : /

И далее следует отметить, что:

... "/" между хостом (или портом) и URL-путем НЕ является частью URL-пути.

В этом случае "?" является частью URL-пути, который

... зависит от используемой схемы, а также от способа ее интерпретации.

Также обратите внимание, что в соответствии со спецификацией вполне допустимо пропуск"/ url-path" - обратите внимание, что "/" было явно включено в этом случае.

Таким образом, "foo.com?bar" недопустим, потому что перед URL-путем нет "/".

4 голосов
/ 13 мая 2013

Добавление к принятому ответу дополнительной информации, которую я нашел после исследования этой проблемы:

http://tools.ietf.org/html/rfc2396

Компоненту доступа предшествует двойная косая черта "//", и она завершается следующей косой чертой "/", знаком вопроса "?" Или концом URI. В компоненте полномочий символы «;», «:», «@», «?» И «/» зарезервированы

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

http://tools.ietf.org/html/rfc1738 (теги заменены)

{путь} является необязательным, как и {searchpart} и предшествующее ему "?". Если нет ни {path}, ни {searchpart}, символ «/» также может быть пропущен.

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

В реальном мире мне ранее удавалось опускать косую черту перед значением запроса, но недавно обнаружил ситуацию, которая падает. Если у вас есть запрос, такой как http://my.domain.com? Do = что-то , и вы просматриваете HTML-страницу в Internet Explorer, ссылка IE10 фиксирует fixed . Если вы затем нажмете Файл, Отправить, Страница по электронной почте ..., ссылка будет добавлена ​​в электронное письмо с неверным форматом. Проблемы зависят от содержимого значения запроса, но мы смогли создать недопустимые URL.

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

4 голосов
/ 24 октября 2009

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

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

...