Символы, разрешенные в URL

кто-нибудь знает полный список символов, которые можно использовать в вам без кодирования? На данный момент я использую A-Z a-z и 0-9... но я хочу узнать полный список.

меня также интересует, есть ли спецификация, выпущенная для предстоящего добавления китайских, арабских url-адресов (как очевидно, что это будет иметь большое влияние на мой вопрос)

8 ответов


С RFC 1738 спецификация:

таким образом, только буквенно-цифровые, специальные символы"$-_.+!*'(),", и зарезервированные символы, используемые для зарезервированных целей unencoded внутри 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

символы, разрешенные в URI, зарезервированы или не защищены (или символ процента как часть процентной кодировки)

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

говорит это RFC 3986 незарезервированных символов (sec. 2.3) а также зарезервированные символы (sec 2.2), если они должны сохранить свое особое значение. А также процентный характер как часть процента-кодирование.


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

- Это любой символ в следующем наборе:

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

С здесь

таким образом, только буквенно-цифровые, специальные символы $-_.+!*'(), и зарезервированные символы, используемые для их зарезервированные цели могут использоваться без кодирования в URL-адресе.


я протестировал его, запросив мой веб-сайт (apache) со всеми доступными символами на моей немецкой клавиатуре в качестве параметра URL:

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

они не были закодированы:

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

не закодировано после urlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

не закодировано после rawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

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

дополнительный тест, который я сделал, касался автоматического связывания в почтовых текстах. Я тестировал Mozilla Thunderbird, aol.com, outlook.com, gmail.com, gmx.de и yahoo.de и они полностью связали url, содержащие эти символы:

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

конечно ? тоже был связан, но только если он использовался один раз.

некоторые люди теперь предложили бы к используйте только rawurlencode() chars, но вы когда-нибудь слышали, что у кого-то были проблемы с открытием этих сайтов?

Asterisk
http://wayback.archive.org/web/*/http://google.com

Colon
https://en.wikipedia.org/wiki/Wikipedia:About

Plus
https://plus.google.com/+google

знак, двоеточие, запятая и восклицание mark
https://www.google.com/maps/place/USA/@36.2218457,...

из-за этого эти символы должны использоваться без проблем. Конечно, вы не должны использовать &; из-за кодирования последовательностей, таких как &amp;. Та же причина действительна для % как он используется для кодирования символов в целом. И = поскольку он присваивает значение имени параметра.

наконец, я бы сказал, что это нормально использовать эти unencoded:

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

но если вы ожидаете случайно сгенерированные URL-адреса, вы не должны использовать .!, потому что они отмечают конец предложения, и некоторые почтовые приложения не будут автоматически связывать последний символ url. Пример:

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

перечислены в RFC3986. Вижу собрал ABNF для URI чтобы увидеть, что разрешено, где и выражение для разбора/проверки.


предстоящее изменение для китайских, арабских доменных имен не URIs. Интернационализированные URI называются IRIs и определяются в RFC 3987. Однако, сказав, что я бы рекомендовал не делать это самостоятельно, а полагаться на существующую, проверенную библиотеку, поскольку есть много вариантов кодирования/декодирования URI и того, что считается безопасным по спецификации, по сравнению с тем, что безопасно при фактическом использовании (браузеры).


RFC3986 определяет два набора символов, которые можно использовать в URI:

  • Зарезервированные Символы: :/?#[]@!$&'()*+,;=

    reserved = gen-delims / sub-delims

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

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

    цель зарезервированные символы-обеспечить набор разграничение символов, отличимых от других данных в URI. Uri, которые отличаются заменой зарезервированного символа соответствующим октетом в процентах, не эквивалентны.

  • Незарезервированных Символов: A-Za-z0-9-_.~

    unreserved = Альфа / цифра /" -"/"."/ "_" / "~"

    вызываются символы, которые разрешены в URI, но не имеют зарезервированной цели безоговорочный.