Какие символы должны быть экранированы в строке HTTP-запроса? - PullRequest
46 голосов
/ 24 февраля 2010

Этот вопрос касается символов в части строки запроса URL-адреса, которые появляются после символа ?.

В Википедии , некоторые символы остаются без изменений, а другие кодируются (обычно с помощью % escape-последовательности).

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

Пример противоречия 1:

Спецификация HTML говорит, что кодирует пространство как +, а все остальное принимает значение RFC1738 . Однако в этом RFC говорится, что ~ небезопасно и, кроме того, что «все небезопасные символы должны всегда кодироваться в URL». Кажется, это противоречит Википедии.

На практике IE8 кодирует ~ в строках запроса, которые он генерирует, а FF3 оставляет его как есть.

Противоречие Пример 2:

Википедия утверждает, что все символы, которые она не упоминает, должны быть закодированы. ! не упоминается в Википедии. Но RFC1738 утверждает, что ! является «специальным» символом и «может использоваться без кодировки». Кажется, это противоречит Википедии, в которой говорится, что она должна быть закодирована.

На практике IE8 кодирует ! в строках запроса, которые он генерирует, в то время как FF3 оставляет его как есть.

Я понимаю, что мораль этого, вероятно, будет заключаться в кодировании тех символов, которые вызывают сомнения между Википедией и спецификациями. Возможно, даже заходит так далеко, что кодирует все, что не является [A-Za-z0-9]. Я просто хотел бы знать фактические стандарты по этому вопросу.

Выводы

Алгоритм, описанный в Википедии, кодирует именно те символы, которые не являются RFC3986 незарезервированными символами . То есть он кодирует все символы, кроме буквенно-цифровых символов и -._~. В особом случае пробел кодируется как + вместо %20 согласно RFC3986.

Некоторые приложения используют более старый RFC. Для сравнения, RFC2396 незарезервированные символы являются буквенно-цифровыми и !'()*-._~.

Для сравнения, Алгоритм рабочего проекта HTML5 кодирует все символы, кроме буквенно-цифровых символов и *-._. В особом случае кодировка для места остается +. Заметные различия заключаются в том, что * не кодируется, а ~ кодируется. (Технически, эта обработка * совместима с RFC3986, даже если * находится в reserved, потому что это в sub-delims, которые разрешены в производстве query.)

1 Ответ

42 голосов
/ 08 июля 2015

Ответ содержится в документе RFC 3986, в частности Раздел 3.4 .

Компонент запроса обозначается первым вопросом знак ("?") и оканчивается символом цифры ("#") или к концу URI.

...

Символ косой черты ("/") и вопросительный знак ("?") Могут представлять данные внутри компонента запроса.

Технически, RFC 3976-3.4 определяет компонент запроса как:

query       = *( pchar / "/" / "?" )

Этот синтаксис означает, что запрос может включать все символы из pchar, а также / и ?. pchar относится к другой спецификации символов пути. Полезно, что В Приложении A к RFC 3986 перечислены соответствующие определения ABNF, в частности:

query         = *( pchar / "/" / "?" )
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

Таким образом, в дополнение ко всем буквенно-цифровым и процентным кодированным символам , запрос может по закону включать следующие не кодированные символы:

/ ? : @ - . _ ~ ! $ & ' ( ) * + , ; =

Конечно, вы можете иметь в виду, что '=' и '&' обычно имеют особое значение в запросе.

...