Какие символы недействительны?
Какие символы делают URL недопустимым?
Являются ли эти допустимые URL-адреса?
-
example.com/file[/].html
-
http://example.com/file[/].html
Ответы
Ответ 1
Обычно URI, определенные в RFC 3986 (см. Раздел 2: символы), могут содержать любой из следующих 84 символов:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
Обратите внимание, что в этом списке не указано, где в URI могут присутствовать эти символы.
Любой другой символ должен быть закодирован с помощью процентного кодирования (%
hh
). Каждая часть URI имеет дополнительные ограничения относительно того, какие символы должны быть представлены словом в кодировке процента.
Ответ 2
Чтобы внести некоторые пояснения и напрямую обратиться к вышеуказанному вопросу, есть несколько классов символов, которые вызывают проблемы для URL-адресов и URI.
Есть некоторые символы, которые запрещены и никогда не должны появляться в URL/URI, зарезервированных символах (описанных ниже) и других символах, которые могут вызывать проблемы в некоторых случаях, но помечаются как "неразумные" или "небезопасные". Объяснения причин ограничения символов четко изложены в RFC-1738 (URL-адреса) и RFC-2396 (URI). Обратите внимание, что более новый RFC-3986 (обновление до RFC-1738) определяет конструкцию символов, которые разрешены в данном контексте, но более старая спецификация предлагает более простое и более общее описание того, какие символы недопустимы с помощью следующие правила.
Исключенные символы US-ASCII, запрещенные в синтаксисе URI:
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space = <US-ASCII coded character 20 hexadecimal>
delims = "<" | ">" | "#" | "%" | <">
Символ "#" исключен, поскольку он используется для ветки URI от идентификатора фрагмента. Символ процента "%" исключен, поскольку он используется для кодирования экранированных символов. Другими словами, "#" и "%" являются зарезервированными символами, которые должны использоваться в определенном контексте.
Список неразумных символов разрешен, но может вызвать проблемы:
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "'"
Символы, которые зарезервированы в компоненте запроса и/или имеют специальное значение в URI/URL:
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
Вышеуказанный "зарезервированный" синтаксический класс относится к тем символам, которые разрешены в URI, но которые не могут быть разрешены в конкретном компоненте общего синтаксиса URI. Символы в "зарезервированном" наборе не зарезервированы во всех контекстах. Например, имя хоста может содержать необязательное имя пользователя, поэтому это может быть что-то вроде ftp://[email protected]/
, где символ "@" имеет особое значение.
Вот пример URL, который содержит недопустимые и неразумные символы (например, "$", "[','] ') и должен быть правильно закодирован:
http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg
Некоторые ограничения символов для URI/URL-адресов зависят от языка программирования. Например, '|' (0x7C), хотя в спецификации URI помечен только как "неразумный", в конструкторе Java java.net.URI будет выброшено исключение URISyntaxException, поэтому URL-адрес, такой как http://api.google.com/q?exp=a|b
, недопустим и должен кодироваться вместо этого как http://api.google.com/q?exp=a%7Cb
, если используется Java с экземпляром объекта URI.
Ответ 3
Это не просто вопрос о персонажах. Различные символы являются законными в разных точках. Например, согласно RFC 2396, unescaped '?' является законным в части фрагмента, но не частью пути.
Вам нужно прочитать RFC 2396, чтобы понять подробности... или задать более конкретный вопрос. Или, если вы действительно имеете в виду URI, а не URL, RFC 3986 - это то, что вы должны читать.
Вы спрашиваете, действительный ли URL example.com/file[/].html
.
Я согласен с Домиником Сейерсом - Нет. URL должен иметь явную схему, такую как "http", а затем ':'
.
Но затем Доминик говорит, что http://example.com/file[/].html
тоже не является допустимым URL, и это не так ясно.
Символы '['
и ']'
являются символами <reserved>
и должны иметь процент экранирования, если не использоваться в качестве разделителей в синтаксисе, специфичном для схемы. Спектр говорит:
"URI, создающие приложения, должны иметь октеты данных с процентным кодированием, которые соответствуют символам зарезервированного набора, если только эти символы не разрешены схемой URI для представления данных в этом компоненте."
(Примечание - оперативное слово здесь "должно", а не "должно" или "необходимо". Этот язык является рекомендательным, а не предписывающим.)
Следующее предложение спецификации говорит следующее:
"Если зарезервированный символ найден в компоненте URI, и для этого символа не определена роль разграничения, тогда его следует интерпретировать как представляющий октет данных, соответствующий этой кодировке символов в US-ASCII."
(Обратите внимание, что оперативное слово "must". Это говорит о том, что означает URI, если кто-то игнорирует совет предыдущего предложения.)
Итак, как это применимо здесь? Хорошо HTTP - это "иерархическая" схема, а общий ABNF для иерархических схем не говорит о том, что '['
или ']'
являются разделителями в <path>
. С другой стороны, ABNF говорит, что a <path segment>
состоит из символов <unreserved>
, <sub-delimiters>
, процентов-кодированных символов, ':'
или '@'
. Другими словами, '['
или ']'
не допускаются строгим чтением ABNF.
Таким образом, строго "http://example.com/file[/].html"
недействительно. Но если вы столкнулись с таким URL (и не решили отклонить его), более ранняя часть спецификации говорит о том, что символы '['
и ']'
должны рассматриваться как символы данных. Таким образом, URL-адрес будет анализироваться как:
- схема ==
"http"
- авторитет ==
"example.com"
- path ==
"/file[/].html"
И путь должен анализироваться как '/' <segment> '/' <segment>
, где первый сегмент "file["
, а второй - "].html"
Ответ 4
Большинство существующих ответов здесь нецелесообразно, поскольку они полностью игнорируют реальное использование таких адресов, как:
Во-первых, отступление к терминологии. Каковы эти адреса? Это действительные URL-адреса?
Исторически ответ был "нет". Согласно RFC 3986, с 2005 года такие адреса не являются URI (и, следовательно, не являются URL-адресами, поскольку URL-адреса являются типом URI). Согласно терминологии стандартов IETF 2005 года, мы должны правильно называть их IRI (интернационализированные идентификаторы ресурсов), как определено в RFC 3987, которые технически не являются URI, но могут быть преобразованы в URI просто путем процентного кодирования всех не -ASCII символы в IRI.
Согласно современной спецификации, ответ - "да". WHATWG Living Standard просто классифицирует все, что раньше называлось "URIs" или "IRI", как "URL". Это приводит терминологию в соответствие с тем, как обычные люди, которые не читали спецификацию, используют слово "URL", которое было одной из целей спецификации.
Какие символы разрешены в соответствии со стандартом жизни WHATWG?
В соответствии с более новым значением "URL", какие символы разрешены? Во многих частях URL, таких как строка запроса и путь, нам разрешено использовать произвольные "единицы URL", которые являются
URL code points и percent-encoded bytes.
Что такое "кодовые точки URL"?
The URL code points are ASCII alphanumeric, U+0021 (!), U+0024 ($), U+0026 (&), U+0027 ('), U+0028 LEFT PARENTHESIS, U+0029 RIGHT PARENTHESIS, U+002A (*), U+002B (+), U+002C (,), U+002D (-), U+002E (.), U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+003F (?), U+0040 (@), U+005F (_), U+007E (~), и code points in the range U+00A0 to U+10FFFD, inclusive, excluding surrogates и noncharacters.
(Обратите внимание, что список "кодовых точек URL" не включает в себя %
, но %
допускается в "кодовых единицах URL", если они являются частью последовательности кодирования процентов.)
Единственное место, которое я могу определить, где спецификация разрешает использование любого символа, которого нет в этом наборе, находится на хосте, где адреса IPv6 заключены в символы [
и ]
. Повсюду в URL разрешены либо единицы измерения URL, либо еще более ограничительный набор символов.
Какие символы были разрешены по старым RFC?
Ради истории, и так как он не был полностью исследован в других местах в ответах здесь, пусть исследование разрешено в соответствии со старшей парой спецификаций.
Прежде всего, у нас есть два типа RFC 3986 зарезервированных символов:
:/?#[]@
, которые являются частью общего синтаксиса для URI, определенного в RFC 3986
!$&'()*+,;=
, которые не являются частью общего синтаксиса RFC, но зарезервированы для использования в качестве синтаксических компонентов определенных схем URI. Например, точки с запятой и запятые используются как часть синтаксиса URI данных, а &
и =
используются как часть вездесущего формата ?foo=bar&qux=baz
в строках запроса (который не является указано в RFC 3986).
Любой из вышеупомянутых зарезервированных символов может быть юридически использован в URI без кодирования, либо для обслуживания их синтаксической цели, либо просто в качестве буквенных символов в данных в некоторых местах, где такое использование не может быть неверно истолковано как символ, служащий его синтаксической цели. (Например, хотя /
имеет синтаксическое значение в URL-адресе, вы можете использовать его без кода в строке запроса, поскольку оно не имеет значения в строке запроса.)
RFC 3986 также определяет некоторые незарезервированные символы, которые всегда можно использовать просто для представления данных без какой-либо кодировки:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
Наконец, сам символ %
разрешен для процентного кодирования.
Это оставляет только следующие символы ASCII, которые запрещено появляться в URL:
- Управляющие символы (символы 0-1F и 7F), включая новую строку, символ табуляции и возврат каретки.
"<>\^'{|}
Любой другой символ из ASCII может быть юридически представлен в URL.
Затем RFC 3987 расширяет этот набор незарезервированных символов следующими диапазонами символов Юникода:
%xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
/ %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
/ %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
/ %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
/ %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
/ %xD0000-DFFFD / %xE1000-EFFFD
Эти варианты блоков из старой спецификации кажутся странными и произвольными, учитывая последние определения блоков Unicode; Вероятно, это связано с тем, что блоки были добавлены за десятилетие, прошедшее с момента написания RFC 3987.
Наконец, возможно, стоит отметить, что простого знания того, какие символы могут юридически появляться в URL-адресе, недостаточно для определения того, является ли данная строка допустимым URL-адресом или нет, поскольку некоторые символы допустимы только в определенных частях URL-адреса. Например, зарезервированные символы [
и ]
допустимы как часть литерального хоста IPv6 в URL-адресе, подобном http://[1080::8:800:200C:417A]/foo, но недопустимы в любом другом контексте, поэтому пример OP http://example.com/file[/].html
недопустим.
Ответ 5
В дополнительном вопросе вы задали вопрос, является ли www.example.com/file[/].html
допустимым URL.
Этот URL-адрес недействителен, потому что URL-адрес является типом URI, а допустимый URI должен иметь схему типа http:
(см. RFC 3986).
Если вы хотите спросить, является ли http://www.example.com/file[/].html
допустимым URL-адресом, тогда ответа по-прежнему нет, потому что символы квадратной скобки там недействительны.
Символы с квадратной скобкой зарезервированы для URL-адресов в этом формате: http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(т.е. литерал IPv6 вместо имени хоста)
Стоит внимательно прочитать RFC 3986, если вы хотите полностью понять проблему.
Ответ 6
Все допустимые символы, которые можно использовать в URI (URL является типом URI), определены в RFC 3986.
Все остальные символы могут быть использованы в URL-адресе при условии, что они сначала "закодированы". Это включает в себя изменение недопустимого символа для определенных "кодов" (обычно в форме символа процента (%), за которым следует шестнадцатеричное число).
Эта ссылка, HTML HTML Encoding Reference, содержит список кодировок для недопустимых символов.
Ответ 7
Несколько из диапазонов символов Unicode действительны HTML5, хотя, возможно, это не будет хорошей идеей их использования.
Например, href
docs say http://www.w3.org/TR/html5/links.html#attr-hyperlink-href:
Атрибут href для элементов a и area должен иметь значение, которое является допустимым URL, потенциально окруженным пробелами.
Тогда определение "действительный URL" указывает на http://url.spec.whatwg.org/, в котором говорится, что он нацелен на:
Выполните выравнивание RFC 3986 и RFC 3987 с помощью современных реализаций и устаревших в процессе.
Этот документ определяет URL-коды URL как:
ASCII буквенно-цифровые, "!", "$", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", ":", ";", "=", "?", "@", "_", "~" и кодовые точки в диапазонах U + 00A0 до U + D7FF, U + E000 U + FDCF, U + FDF0 до U + FFFD, U + 10000 - U + 1FFFD, U + 20000 - U + 2FFFD, U + 30000 - U + 3FFFD, U + 40000 - U + 4FFFD, U + 50000 - U + 5FFFD, U + 60000 - U + 6FFFD, U + 70000 - U + 7FFFD, U + 80000 - U + 8FFFD, U + 90000 - U + 9FFFD, U + A0000 - U + AFFFD, U + B0000 - U + BFFFD, U + C0000 - U + CFFFD, U + D0000 - U + DFFFD, U + E1000 - U + EFFFD, U + F0000 - U + FFFFD, U + 100000 - U + 10FFFD.
В заявлении используется термин "URL-коды кодов":
Если c не является кодовой точкой URL, а не "%", ошибка синтаксического анализа.
в нескольких частях алгоритма синтаксического анализа, включая отношения схемы, полномочий, относительного пути, запроса и фрагмента: так что в основном весь URL.
Кроме того, валидатор http://validator.w3.org/ передает URL-адреса, такие как "你好"
, и не передает URL-адреса с такими символами, как пробелы "a b"
Конечно, как упоминал Стивен С, речь идет не только о персонажах, но и о контексте: вы должны понимать весь алгоритм. Но поскольку в ключевых точках алгоритма используется класс "URL-коды кода", это дает хорошее представление о том, что вы можете использовать или нет.
Смотрите также: символы Юникода в URL-адресах
Ответ 8
Мне нужно выбрать символ для разделения URL-адресов в строке, поэтому я решил создать список символов, который сам по себе не найден в URL:
>>> allowed = "-_.~!*'();:@&=+$,/?%#[][email protected]"
>>> from string import printable
>>> ''.join(set(printable).difference(set(allowed)))
'`" <\x0b\n\r\x0c\\\t{^}|>'
Таким образом, возможны варианты: новая строка, табуляция, пробел, обратная косая черта и "<>{}^|
. Думаю, я пойду с пространством или новой линией.:)
Ответ 9
Не совсем ответ на ваш вопрос, но проверка url действительно серьезная p.i.t.a
Возможно, вам просто лучше проверить доменное имя и оставить запрос частью URL-адреса. Это мой опыт.
Вы также можете прибегнуть к проверке URL-адреса и выяснению, приводит ли он к действительному ответу, но это может быть слишком большим для такой простой задачи.
Регулярные выражения для обнаружения URL-адреса в изобилии, google it:)
Ответ 10
Используйте urlencode, чтобы разрешить произвольные символы в вашем URL-адресе.
Ответ 11
Я придумал пару регулярных выражений для PHP, которые преобразуют URL-адреса в текст для привязки тегов. (Сначала он преобразует все www. Urls в http://затем преобразует все URL-адреса с помощью https?://в href=... html links
$string = preg_replace('/(https?:\/\/)([!#$&-;=?\-\[\]_a-z~%]+)/sim', '<a href="$1$2">$2</a>',
preg_replace('/(\s)((www\.)([!#$&-;=?\-\[\]_a-z~%]+))/sim', '$1http://$2', $string)
);