Безопасно ли использовать двоеточие `:` для дружественных URL-адресов?
Мы разрабатываем систему URL, которая будет указывать разделы приложения как слова, разделенные косой чертой. В частности, это в GWT, поэтому соответствующие части URL будут в хэше (что будет интерпретировано уровнем контроллера на стороне клиента):
http://site/gwturl#section1/section2
Некоторые разделы могут нуждаться в дополнительных атрибутах, которые мы хотели бы указать с помощью :
, так что части раздела URL являются однозначными. Код будет разделен сначала на /
, Затем на :
, как это:
http://site/gwturl#user:45/comments
Конечно, мы делаем это для удобства работы с URL, поэтому мы хотели бы убедиться, что ни один из этих символов, которые будут иметь особое значение, не будет кодироваться по URL браузерами или любой другой системой, и в итоге получится URL-адрес этот:
http://site/gwturl#user%3A45/comments <--- BAD
Безопасно ли использовать двоеточие таким образом (я имею в виду, что оно не будет автоматически кодироваться) для браузеров, систем закладок, даже кода Javascript или Java?
11 ответов
Я недавно написал кодировщик URL, так что это довольно свежо в моей памяти.
http://site/gwturl#user:45/comments
Все символы в части фрагмента (user:45/comments
) абсолютно законны для RFC 3986 URI.
Соответствующие части ABNF:
fragment = *( pchar / "/" / "?" )
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
Помимо этих ограничений, часть фрагмента не имеет определенной структуры, кроме той, которую предоставляет ваше приложение. Схема http только говорит о том, что вы не отправляете эту часть на сервер.
РЕДАКТИРОВАТЬ:
D'о!
Несмотря на мои утверждения о спецификации URI, программа irreputable дает правильный ответ, когда указывает, что спецификация HTML 4 ограничивает имена / идентификаторы элементов.
Обратите внимание, что правила идентификатора меняются в HTML 5. Ограничения URI будут по-прежнему применяться (на момент написания статьи существуют некоторые нерешенные проблемы, связанные с использованием URI в HTML 5).
MediaWiki и другие вики-движки используют двоеточия в своих URL для обозначения пространств имен, без каких-либо серьезных проблем.
В дополнение к анализу Макдауэлла по стандарту URI, помните также, что фрагмент должен быть действительным именем привязки HTML. Согласно http://www.w3.org/TR/html4/types.html
Токены ID и NAME должны начинаться с буквы ([A-Za-z]) и могут сопровождаться любым количеством букв, цифр ([0-9]), дефисов ("-"), подчеркиваний ("_"), двоеточия (":") и точки (".").
Так что тебе повезло. ":" явно разрешено. И никто не должен "%"- избегать его, не только потому, что "%" там недопустимый символ, но также и потому, что фрагмент во многом соответствует имени привязки char-by-char, поэтому ни один агент не должен пытаться умерить их в любом случае.
Однако вы должны проверить это. Веб-стандарты не соблюдаются строго, иногда стандарты противоречат друг другу. Например, HTTP/1.1 RFC 2616 не допускает строку запроса в URL запроса, в то время как HTML создает ее при отправке формы методом GET. Все, что реализовано в реальном мире, побеждает в конце дня.
Я бы на это не рассчитывал. Скорее всего, URL будет закодирован как %3A
многими пользовательскими агентами.
От URLEncoder
Javadoc:
Для получения дополнительной информации о кодировке формы HTML обратитесь к спецификации HTML.
При кодировании строки применяются следующие правила:
- Буквенно-цифровые символы от "a" до "z", от "A" до "Z" и от "0" до "9" остаются неизменными.
- Специальные символы ".", "-", "*" и "_" остаются прежними.
- Символ пробела "" преобразуется в знак плюс "+".
- Все остальные символы небезопасны и сначала преобразуются в один или несколько байтов с использованием некоторой схемы кодирования. Затем каждый байт представляется трехсимвольной строкой "%xy", где xy - это шестнадцатеричное представление байта из двух цифр. Рекомендуемая схема кодирования - UTF-8. Однако из соображений совместимости, если кодировка не указана, используется кодировка платформы по умолчанию.
То есть, :
не безопасно
Google также использует двоеточие.
В этой спецификации они используют двоеточия для имен пользовательских методов.
Я не вижу, чтобы Firefox или IE8 кодировали некоторые URL-адреса Википедии, содержащие этот символ.
Двоеточие используется как разделение между именем пользователя и паролем, если протокол требует аутентификации.
АпачиURIBuilder
и JAX-RSUriBuilder
классы обрабатываются по-разному (они также по-разному относятся к фигурным скобкам)
new URIBuilder("http://localhost").setCustomQuery("foo=a:b&bar={}").buildString()
выходы
http://localhost?foo=a:b&bar=%7B%7D
UriBuilder.fromPath("http://localhost").queryParam("foo", "a:b").queryParam("bar", "{}").toTemplate()
выходы
http://localhost?foo=a%3Ab&bar={}
Итак, Apache URIBuilder, похоже, не кодирует:
но он кодирует{}
а для JAX-RS UriBuilder все наоборот.
Это небезопасный символ и используется для определения того, к какому порту вы подключаетесь, когда он находится сразу после вашего доменного имени