Этот вопрос касается символов в строке строки запроса URL-адреса, которые появляются после символа ?
.
Per Wikipedia, некоторые символы остаются как есть и другие кодируются (обычно с escape-последовательностью %
).
Я пытаюсь отследить это до фактических спецификаций, так что я понимаю обоснование каждой точки маркера на этой странице в Википедии.
Противоречие Пример 1:
HTML-спецификация говорит, чтобы кодировать пространство как +
и откладывает остальное на RFC1738. Тем не менее, этот RFC говорит, что ~
является небезопасным и, кроме того, что "[a] ll небезопасные символы всегда должны быть закодированы в URL". Это, кажется, противоречит Википедии.
На практике IE8 кодирует ~
в строках запроса, которые он генерирует, а FF3 оставляет его как есть.
Противоречие Пример 2:
Википедия заявляет, что все символы, которые она не упоминает, должны быть закодированы. !
не упоминается в Википедии. Но RFC1738 утверждает, что !
является "специальным" символом и "может быть использован незакодированным". Это, похоже, противоречит Википедии, в которой говорится, что она должна быть закодирована.
На практике IE8 кодирует !
в строках запроса, которые он генерирует, а FF3 оставляет его как есть.
Я понимаю, что мораль этого, вероятно, будет заключаться в кодировании тех персонажей, которые сомневаются между Википедией и спецификациями. Возможно, даже если кодировать все, что не является [A-Za-z0-9]. Я просто хотел бы узнать фактические стандарты этого.
Выводы
Алгоритм, описанный в Википедии, кодирует именно те символы, которые не являются RFC3986 безоговорочными символами. То есть, он кодирует все символы, отличные от буквенно-цифровых символов, и -._~
. В качестве специального случая пространство кодируется как +
вместо %20
для RFC3986.
В некоторых приложениях используется более ранний RFC. Для сравнения, RFC2396 unreserved characters - буквенно-цифровые и !'()*-._~
.
Для сравнения, HTML5 рабочий алгоритм работы кодирует все символы, кроме буквенно-цифровых и *-._
. Кодировка специального случая для пробела остается +
. Заметные отличия заключаются в том, что *
не кодируется и ~
кодируется. (Технически эта обработка *
совместима с RFC3986, хотя *
находится в reserved
, потому что она находится в sub-delims
, которая разрешена в работе query
.)