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

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

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

Ответ 1

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

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

РЕДАКТИРОВАТЬ: Как правильно указывает @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

Ответ 2

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

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

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

Ответ 3

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

Это любой символ из следующего набора регулярных выражений:

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

Ответ 4

Я протестировал его, запросив мой сайт (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(), но слышали ли вы, что у кого-то были проблемы с открытием этих веб-сайтов?

звездочка
http://wayback.archive.org/web/*/http://google.com

Двоеточие
https://en.wikipedia.org/wiki/Wikipedia:About

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

Знак, Colon, Comma и восклицательный знак
https://www.google.com/maps/place/USA/@36.2218457,...

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

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

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

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

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

Ответ 5

От здесь

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

    reserved = gen-delims/sub-delims

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

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

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

  • Unreserved Characters: A-Za-z0-9-_.~

    unreserved = ALPHA/DIGIT/"- "/". "/" _ "/" ~"

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