Які символи роблять 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 - адреса». Це узгоджує вказану термінологію з тим, як звичайні люди, які не читали специфікацію, використовують слово "URL", що було однією з цілей специфікації .
Які нові символи "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, але не є законними в будь-якому іншому контексті, тому Приклад ОП - 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-адресі за умови, що вони спочатку "кодовані URL-адресою". Це передбачає зміну недійсного символу для конкретних "кодів" (як правило, у вигляді відсотка символу (%) з наступним шістнадцятковим числом).
Це посилання, HTML Посилання на кодування URL-адреси , містить список кодувань для недійсних символів.
Кілька діапазонів символів Unicode є дійсним HTML5 , хоча, можливо, все-таки не дуже корисно їх використовувати.
Наприклад, href
документи кажуть http://www.w3.org/TR/html5/links.html#attr-hyperlink-href :
Атрибут href для елементів а та області повинен мати значення, яке є дійсною 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-адреси коду" використовується в ключових точках алгоритму, він дає гарне уявлення про те, що ви можете використовувати чи ні.
Дивіться також: символи Unicode в 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 it :)
Я реалізую старий 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-адреси в тексті в якірні теги. (Спочатку він перетворює всі www. Urls в 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)
);