Какие символы делают URL недействительным?
Это действительные URL?
example.com/file[/].html
http://example.com/file[/].html
Какие символы делают URL недействительным?
Это действительные URL?
example.com/file[/].html
http://example.com/file[/].html
Ответы:
В целом URI, определенные в RFC 3986 (см. Раздел 2: Символы ), могут содержать любой из следующих 84 символов:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
Обратите внимание, что в этом списке не указано, где в URI могут присутствовать эти символы.
Любой другой символ должен быть закодирован с помощью процентного кодирования ( %
hh
). Каждая часть URI имеет дополнительные ограничения относительно того, какие символы должны быть представлены словом в кодировке процента.
/^([!#$&-;=?-[]_a-z~]|%[0-9a-fA-F]{2})+$/
было ли что-то еще, что вы нашли, что он должен был принять? (Просто чтобы прояснить, это регулярное выражение проверяет только, содержит ли строка допустимые символы URL, а не если строка содержит правильно сформированный URL.)
Чтобы добавить некоторые пояснения и непосредственно обратиться к вышеупомянутому вопросу, есть несколько классов символов, которые вызывают проблемы для 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://user@hostname/
где символ «@» имеет особое значение.
Вот пример URL, который содержит недопустимые и неразумные символы (например, $, [], ']') и должен быть правильно закодирован:
http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg
Некоторые ограничения символов для URI / URL зависят от языка программирования. Например, '|' Символ (0x7C), хотя в спецификации URI помечен только как «неразумный», будет вызывать исключение URISyntaxException в конструкторе Java java.net.URI, поэтому URL-адрес http://api.google.com/q?exp=a|b
недопустим и должен быть закодирован вместо http://api.google.com/q?exp=a%7Cb
использования Java с экземпляром объекта URI.
?
все в порядке в разделе запросов, но невозможно до него, и я не думаю, что он @
принадлежит ни к одному из этих списков. О, а не %25
в последней строке, ты имеешь в виду %7C
?
Большинство существующих ответов здесь нецелесообразно, потому что они полностью игнорируют реальное использование адресов, таких как:
Во-первых, отступление к терминологии. Что есть эти адреса? Это действительные URL?
Исторически ответ был «нет». Согласно RFC 3986 , с 2005 года такие адреса не являются URI (и, следовательно, не URL-адресами, поскольку URL-адреса являются типом URI). ). Согласно терминологии стандартов IETF 2005 года, мы должны правильно называть их IRI (интернационализированные идентификаторы ресурсов), как определено в RFC 3987 , которые технически не являются URI, но могут быть преобразованы в URI просто путем процентного кодирования всех не-ASCII-символов в IRI ,
Согласно современной спецификации, ответ - «да». WHATWG Living Standard просто классифицирует все , что было ранее называться «URIs» или «ИРИС» , как «URL - адрес». Это выравнивает терминологию specced с тем, как обычные люди, которые не читали спецификацию, используют слово «URL», которое было одним из спецификаций. целей .
В соответствии с более новым значением «URL», какие символы разрешены? Во многих частях URL, таких как строка запроса и путь, мы можем использовать произвольные «единицы URL» , которые
Что такое «кодовые точки URL»?
В точках URL кода являются ASCII алфавитно - цифровой, U + 0021 (!), U + 0024 ($), U + 0026 (&), U + 0027 ( '), U + 0028 скобка, U + 0029 закрывающая скобка, 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 (~) и кодовые точки в диапазоне от U + 00A0 до U + 10FFFD включительно, исключая суррогаты и нехарактеры.
(Обратите внимание, что список «кодовых точек URL» не включает %
, но%
они разрешены в «единицах кодового URL», если они являются частью последовательности кодирования процентов.)
Единственное место, которое я могу определить, где спецификация разрешает использование любого символа, которого нет в этом наборе, находится на хосте , где IPv6-адреса заключены в [
и]
символах. Повсюду в URL разрешены либо единицы измерения URL, либо еще более ограничительный набор символов.
Ради истории, и поскольку это не было полностью изучено в других разделах ответов, давайте рассмотрим, было разрешено в соответствии с более старой парой спецификаций.
Прежде всего, у нас есть два типа зарезервированных символов RFC 3986 :
:/?#[]@
, которые являются частью общего синтаксиса для URI, определенного в RFC 3986!$&'()*+,;=
, которые не являются частью общего синтаксиса RFC, но зарезервированы для использования в качестве синтаксических компонентов определенных схем URI. Например, точка с запятой и запятые используются в качестве части синтаксиса URI , данных , а также &
и =
используются в качестве части повсеместного ?foo=bar&qux=baz
формата в строках запроса (который не указанный в RFC 3986).Любой из зарезервированных символов, приведенных выше, может быть законно использован в URI без кодирования, либо для обслуживания их синтаксической цели, либо просто в качестве литеральных символов в данных в некоторых местах, где такое использование не может быть неверно истолковано как символ, служащий его синтаксической цели. (Например, хотя он /
имеет синтаксическое значение в URL-адресе, вы можете использовать его без кода в строке запроса, поскольку он не имеет значения в строке запроса.)
RFC 3986 также определяет некоторые незарезервированные символы, которые всегда можно использовать просто для представления данных без какой-либо кодировки:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
Наконец, сам %
символ разрешен для процентного кодирования.
Это оставляет только следующие символы ASCII, которые запрещено появляться в URL:
"<>\^`{|}
Любой другой символ из 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
является незаконным.
В своем дополнительном вопросе вы спросили, 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, если вы хотите полностью понять проблему.
[
И ]
не URI действительны в течение почти анализаторов , которые я видел. Это на самом деле облажало меня в реальном мире: stackoverflow.com/questions/11038967/…
Unwise
очень серьезно относиться к URI и все же будут в порядке с URL-библиотеками. То есть нет флага, который можно игнорировать Unwise
. Мне придется проверить, что такое Rust lang (поскольку он создается для браузера, мне интересно, что он делает) для URL. Большинство браузеров, тем не менее, также с радостью передаст "[", "]". Так что в теории, как я уже говорил с C / C ++, они суб / супер, но в действительности это не так. Это сильно зависит от интерпретации спецификации и семантики супер / подмножества.
Все допустимые символы, которые можно использовать в URI ( URL является типом URI ), определены в RFC 3986 .
Все остальные символы могут быть использованы в URL-адресе при условии, что они сначала «закодированы». Это включает в себя изменение недопустимого символа для определенных «кодов» (обычно в форме символа процента (%), за которым следует шестнадцатеричное число).
Эта ссылка, HTML HTML Encoding Reference , содержит список кодировок для недопустимых символов.
Некоторые из диапазонов символов Юникода являются допустимыми HTML5 , хотя их использование может быть не очень хорошей идеей.
Например, в href
документах говорится 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 как:
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
Мне нужно выбрать символ для разделения URL в строке, поэтому я решил создать список символов, который не может быть найден в URL самостоятельно:
>>> allowed = "-_.~!*'();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
>>> from string import printable
>>> ''.join(set(printable).difference(set(allowed)))
'`" <\x0b\n\r\x0c\\\t{^}|>'
Итак, возможны следующие варианты: перевод строки, табуляция, пробел, обратный слеш и "<>{}^|
. Я думаю, я пойду с пробелом или переводом строки. :)
На самом деле это не ответ на ваш вопрос, но проверка URL-адресов - это серьезный вопрос. Вам, вероятно, лучше проверить доменное имя и оставить часть запроса в URL-адресе. Это мой опыт. Вы также можете прибегнуть к проверке URL-адреса и посмотреть, приведет ли он к правильному ответу, но это может быть слишком много для такой простой задачи.
Регулярные выражения для определения URL-адресов в изобилии, Google это :)
Я реализую старый http (0.9, 1.0, 1.1) запрос и ответ читателя / писателя. Запрос URI является наиболее проблемным местом.
Вы не можете просто использовать RFC 1738, 2396 или 3986 как есть. Есть много старых HTTP-клиентов и серверов, которые допускают больше символов. Поэтому я провел исследование на основе случайно опубликованных журналов доступа к веб-серверу:"GET URI HTTP/1.0" 200
.
Я обнаружил, что следующие нестандартные символы часто используются в URI:
\ { } < > | ` ^ "
Эти символы были описаны в RFC 1738 как небезопасные .
Если вы хотите быть совместимым со всеми старыми клиентами и серверами HTTP - вы должны разрешить эти символы в URI запроса.
Пожалуйста, прочитайте больше информации об этом исследовании в http-og .
Я придумал пару регулярных выражений для PHP, которые преобразуют URL-адреса в тексте в теги привязки. (Сначала он преобразует все URL-адреса www. В http: //, затем преобразует все URL-адреса с помощью https?: // в ссылки href = ... html
$string = preg_replace('/(https?:\/\/)([!#$&-;=?\-\[\]_a-z~%]+)/sim', '<a href="$1$2">$2</a>',
preg_replace('/(\s)((www\.)([!#$&-;=?\-\[\]_a-z~%]+))/sim', '$1http://$2', $string)
);