Символи, дозволені в URL-адресі


191

Хтось знає повний список символів, які можна використовувати в GET, не кодуючись? На даний момент я використовую AZ az і 0-9 ..., але я хочу дізнатися повний список.

Мене також цікавить, чи є специфікація, опублікована для подальшого додавання китайських, арабських URL-адрес (як очевидно, це матиме великий вплив на моє питання)


5
Символи, дозволені в URI, є зарезервованими !*'();:@&=+$,/?#[]або незарезервованими A-Za-z0-9_.~-(або відсотковими символами %як частиною відсоткового кодування)
Mikl

1
У MySQL я використовую це REGEXP '[^]A-Za-z0-9_.~!*''();:@&=+$,/?#[%-]+'для пошуку рядка URL-адрес із поганими символами. Може бути, це корисне і для когось іншого.
Мікл

@Mikl: Ця річ навряд чи схожа на звичайний вираз.
Єнс Мандер

Відповіді:


182

З специфікації RFC 1738 :

Таким чином, лише алфавітно-цифрові символи, спеціальні символи " $-_.+!*'()," та зарезервовані символи, які використовуються для зарезервованих цілей, можуть використовуватися некодованими в межах URL-адреси.

EDIT: Як правильно зазначає @Jukka K. Korpela, цей RFC було оновлено RFC 3986 . Це розширило та уточнило символи, дійсні для хоста, на жаль, це не просто скопіювати та вставити, але я зроблю все можливе.

У першому зібраному порядку:

host        = IP-literal / IPv4address / reg-name

IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"

IPvFuture   = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )

IPv6address =         6( h16 ":" ) ls32
                  /                       "::" 5( h16 ":" ) ls32
                  / [               h16 ] "::" 4( h16 ":" ) ls32
                  / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
                  / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
                  / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
                  / [ *4( h16 ":" ) h16 ] "::"              ls32
                  / [ *5( h16 ":" ) h16 ] "::"              h16
                  / [ *6( h16 ":" ) h16 ] "::"

ls32        = ( h16 ":" h16 ) / IPv4address
                  ; least-significant 32 bits of address

h16         = 1*4HEXDIG 
               ; 16 bits of address represented in hexadecimal

IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

dec-octet   = DIGIT                 ; 0-9
              / %x31-39 DIGIT         ; 10-99
              / "1" 2DIGIT            ; 100-199
              / "2" %x30-34 DIGIT     ; 200-249
              / "25" %x30-35          ; 250-255

reg-name    = *( unreserved / pct-encoded / sub-delims )

unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"     <---This seems like a practical shortcut, most closely resembling original answer

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

pct-encoded = "%" HEXDIG HEXDIG

5
@Tim слэш є зарезервованим символом, тому, якщо він використовується за зарезервованою метою (розмежування контурів, розмежування протоколу ...), йому не потрібно бігти. Інакше так і є.
Майлз

4
Загальні синтаксичні правила RFC 1738 були застаріли в 1998 році.
Юкка К. Корпела

3
@Myles, STD 66 (= RFC 3986) згадується в інших відповідях. Чи правильний зміст відповідей - це інше питання; Я не думаю, що жодна з відповідей правильно описує повний список.
Юкка К. Корпела

4
І ви можете додати список незарезервованих A-Za-z0-9_.-~та зарезервованих символів на початку цієї відповіді. !*'();:@&=+$,/?#[]Це може заощадити час для людей
Мікл

2
@basZero Вибачте, що ви вважаєте це заплутаним, але повна відповідь не проста. Відповідь на ваше запитання - ні, оскільки це зарезервований персонаж, як зазначено в:reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
Myles

42

Символи, дозволені в URI, є зарезервованими або незарезервованими (або відсотковими символами як частиною відсоткового кодування)

http://en.wikipedia.org/wiki/Percent-encoding#Types_of_URI_characters

говорить, що це беззастережні символи RFC 3986 (розд. 2.3), а також зарезервовані символи (сек. 2.2), якщо їм потрібно зберегти своє особливе значення. А також відсотковий символ як частина відсоткового кодування.


7
Хоча це посилання може відповісти на питання, краще включити сюди суттєві частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться.
jaestevan

@jaestevan Цитування зв'язаного документа:The characters allowed in a URI are either reserved or unreserved (or a percent character as part of a percent-encoding)
Mikl

26

Повний список із 66 незарезервованих символів знаходиться в RFC3986, тут: http://tools.ietf.org/html/rfc3986#section-2.3

Це будь-який символ у наступному наборі регулярних виразів:

[A-Za-z0-9_.\-~]

2
Ви можете використовувати і ті, що зарезервовані.
Qwerty

Застарілий RFC1738 вказується {}^\~та backtickє небезпечним. І RFC3986 перераховує \ як небезпечні через файлову систему. Ці засоби також {}^можуть бути використані.
mgutt

Тож якщо ви намагаєтеся, скажімо, знайти кінець URL-адреси в рядку (який я є), було б найкраще пройти застарілі стандарти у прийнятій відповіді ... Якщо ви перевіряєте URL-адресу, вам слід використовуйте набір символів у цій відповіді.
ashleedawg

Обережно, ви написали це як звичайний клас персонажів виразів. Переконайтеся , рятуючись від -або поставити його на початку або в кінці класу символів, тому що на [.-~]насправді містить всі символи ASCII від 46 до 126
KWL

19

Я перевірив це, подавши запит на свій веб-сайт (apache) з усіма доступними символами на моїй німецькій клавіатурі як параметр URL:

http://example.com/?^1234567890ß´qwertzuiopü+asdfghjklöä#<yxcvbnm,.-°!"§$%&/()=? `QWERTZUIOPÜ*ASDFGHJKLÖÄ\'>YXCVBNM;:_²³{[]}\|µ@€~

Вони не були закодовані:

^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.-!/()=?`*;:_{}[]\|~

Не кодується після urlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

Не кодується після rawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

Примітка: Перед rawurlencode()кодуванням PHP 5.3.0 ~через RFC 1738 . Але це було замінено RFC 3986, так що його зараз безпечно використовувати. Але я не розумію, чому, наприклад {}, кодуються через те, rawurlencode()що вони не згадуються в RFC 3986.

Додатковий тест, який я зробив, стосувався автоматичного посилання на тексти пошти. Я перевірив Mozilla Thunderbird, aol.com, outlook.com, gmail.com, gmx.de та yahoo.de, і вони повністю пов’язали URL-адреси, що містять ці символи:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~+#,%&=*;:@

Звичайно ?, теж було пов'язано, але тільки якщо воно було використано один раз.

Деякі люди зараз пропонують використовувати лише rawurlencode()символи, але чи чули ви коли-небудь проблеми, щоб відкрити ці веб-сайти?

Зірочка
http://wayback.archive.org/web/*/http://google.com

Колон https://en.wikipedia.org/wiki/Wikipedia: About

Плюс
https://plus.google.com/+google

Під знаком Колон, Кома та знак оклику
https: //www.google.com/maps/place/USA/@36.2218457, ...

Через це ці символи повинні бути без використання кодованими без проблем. Звичайно, ви не повинні використовувати &;через кодування таких послідовностей &amp;. Ця ж причина є дійсною і %для кодування символів в цілому. І =як він привласнює значення імені параметра.

Нарешті, я б сказав, добре використовувати ці незашифровані:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~!+,*:@

Але якщо ви очікуєте генерованих випадковим чином URL-адрес, ви не повинні використовувати .!, оскільки вони позначають кінець речення, а деякі поштові програми не автоматично пов'язують останній знак URL-адреси. Приклад:

Visit http://example.com/foo=bar! !

Практичний підхід - хороша робота. +
Олівер

12

від сюди

Таким чином, лише алфавітно-цифрові символи, спеціальні символи $-_.+!*'(), та зарезервовані символи, які використовуються для їхніх зарезервованих цілей, можуть використовуватися незашифрованими в межах URL-адреси.



6

RFC3986 визначає два набори символів, які можна використовувати в URI:

  • Зарезервовані персонажі ::/?#[]@!$&'()*+,;=

    зарезервовано = gen-delims / sub-delims

    gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"

    sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

    Метою зарезервованих символів є надання набору символів для розмежування, які можна відрізняти від інших даних у URI. URI, які відрізняються заміною зарезервованого символу його відповідним відсотково закодованим октетом, не еквівалентні.

  • Незарезервовані персонажі :A-Za-z0-9-_.~

    незарезервовано = ALPHA / DIGIT / "-" / ". / "_" / "~"

    Символи, дозволені в URI, але не мають зарезервованої мети, називаються незарезервованими.


3

Майбутня зміна стосується китайських, арабських доменних імен, а не URI. Інтернаціоналізовані URI називаються IRI і визначаються в RFC 3987 . Однак, сказавши, що я рекомендую робити це не самостійно, а покладатися на існуючу перевірену бібліотеку, оскільки існує безліч варіантів кодування / декодування URI і те, що вважається безпечним за специфікацією, порівняно з тим, що є безпечним при фактичному використанні (браузери) .


0

Якщо ви хочете надати особливий досвід користувачам, яким ви могли б скористатися pushStateдля залучення широкого кола символів до URL-адреси браузера:

введіть тут опис зображення

var u="";var tt=168;
for(var i=0; i< 250;i++){
 var x = i+250*tt;
console.log(x);
 var c = String.fromCharCode(x);
 u+=c; 
}
history.pushState({},"",250*tt+u);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.