Какие символы делают URL недействительным?
Это действительные URL?
example.com/file[/].htmlhttp://example.com/file[/].html
Какие символы делают URL недействительным?
Это действительные URL?
example.com/file[/].htmlhttp://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)
);