Caracteres permitidos em um URL


190

Alguém sabe a lista completa de caracteres que podem ser usados ​​dentro de um GET sem serem codificados? No momento, estou usando AZ az e 0-9 ... mas estou procurando descobrir a lista completa.

Também estou interessado em saber se há uma especificação liberada para a próxima adição de URLs em chinês e árabe (como obviamente isso terá um grande impacto na minha pergunta)


5
Os caracteres permitidos em um URI ou são reservados !*'();:@&=+$,/?#[]ou sem reservas A-Za-z0-9_.~-(ou um carácter de percentagem %, como parte de um por cento de codificação)
Mikl

1
No MySQL, eu uso isso REGEXP '[^]A-Za-z0-9_.~!*''();:@&=+$,/?#[%-]+'para encontrar URL com caracteres incorretos. Talvez seja útil para outra pessoa também.
Mikl 30/05

@ Mikl: Essa coisa dificilmente parece uma expressão regular.
Jens Mander

Respostas:


181

Da especificação RFC 1738 :

Portanto, apenas alfanuméricos, caracteres especiais " $-_.+!*'()," e caracteres reservados usados ​​para fins reservados podem ser usados ​​sem codificação em um URL.

EDIT: Como aponta corretamente @Jukka K. Korpela, esta RFC foi atualizada pela RFC 3986 . Isso expandiu e esclareceu os caracteres válidos para o host, infelizmente não é fácil copiar e colar, mas farei o meu melhor.

Na primeira ordem correspondente:

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
A barra @Tim é um caractere reservado, portanto, se estiver sendo usada para seu fim reservado (delineando caminhos, delineamento de protocolo ...), não será necessário escapar. Caso contrário, ele faz.
Myles

4
Regras de sintaxe genéricas de RFC 1738 foram tornados obsoletos em 1998.
Jukka K. Korpela

3
@ Styles, STD 66 (= RFC 3986) é mencionado em outras respostas. Se o conteúdo das respostas está correto é uma questão diferente; Acho que nenhuma das respostas descreve corretamente a lista completa.
Jukka K. Korpela 08/03

4
E você pode adicionar uma lista de A-Za-z0-9_.-~caracteres não reservados e reservados no início desta resposta. !*'();:@&=+$,/?#[]Ele pode economizar tempo para as pessoas
Mikl

2
@basZero Sinto muito que você tenha achado confuso, mas a resposta completa não é simples. A resposta para sua pergunta é não, pois é um caractere reservado, conforme indicado por:reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
Myles

42

Os caracteres permitidos em um URI são reservados ou não reservados (ou um caractere de porcentagem como parte de uma codificação de porcentagem)

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

diz que esses são caracteres não reservados para o RFC 3986 (seção 2.3) e caracteres reservados (seção 2.2), caso precisem manter seu significado especial. E também um caractere de porcentagem como parte de uma codificação de porcentagem.


7
Embora esse link possa responder à pergunta, é melhor incluir aqui as partes essenciais da resposta e fornecer o link para referência. As respostas somente para links podem se tornar inválidas se a página vinculada for alterada.
jaestevan

@jaestevan Citação do documento vinculado:The characters allowed in a URI are either reserved or unreserved (or a percent character as part of a percent-encoding)
Mikl

26

A lista completa dos 66 caracteres não reservados está na RFC3986, aqui: http://tools.ietf.org/html/rfc3986#section-2.3

Este é qualquer caractere no seguinte conjunto de expressões regulares:

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

2
Você pode usar aqueles reservados também.
Qwerty

O obsoleto RFC1738 listado {}^\~e backtickcomo inseguro. E o RFC3986 lista \ como não seguro por causa do sistema de arquivos. Isso significa que também {}^pode ser usado.
mgutt

Então, se você está tentando, digamos, encontrar o final de um URL dentro de uma string (o que eu sou), seria melhor seguir os padrões obsoletos na resposta aceita ... Se você estiver validando os URLs, deve use o conjunto de caracteres nesta resposta.
ashleedawg

Cuidado, você escreveu isso como uma classe de caractere de expressão regular. Certifique-se para escapar da -ou colocá-lo no início ou no final da classe de personagem, porque [.-~]na verdade, contém todos os caracteres ASCII de 46 a 126.
kwl

19

Testei-o solicitando meu site (apache) com todos os caracteres disponíveis no meu teclado alemão como parâmetro de URL:

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

Estes não foram codificados:

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

Não codificado após urlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

Não codificado após rawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

Nota: Antes do PHP 5.3.0 rawurlencode()codificado ~por causa da RFC 1738 . Mas isso foi substituído pelo RFC 3986, portanto é seguro usá-lo agora. Mas não entendo por que, por exemplo, {}são codificados rawurlencode()porque não são mencionados na RFC 3986.

Um teste adicional que fiz foi referente à vinculação automática em textos de correio. Testei o Mozilla Thunderbird, aol.com, outlook.com, gmail.com, gmx.de e yahoo.de e eles vincularam completamente os URLs contendo esses caracteres:

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

É claro que o ?link também estava vinculado, mas apenas se fosse usado uma vez.

Algumas pessoas sugerem agora usar apenas os rawurlencode()caracteres, mas você já ouviu falar que alguém teve problemas para abrir esses sites?

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

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

Além disso,
https://plus.google.com/+google

Sinal, dois pontos, vírgula e ponto de exclamação
https: //www.google.com/maps/place/USA/@36.2218457, ...

Por esse motivo, esses caracteres devem ser utilizáveis ​​sem codificação sem problemas. Claro que você não deve usar &;por causa de sequências de codificação como &amp;. O mesmo motivo é válido %, pois costumava codificar caracteres em geral. E =como atribui um valor ao nome de um parâmetro.

Finalmente, eu diria que não há problema em usar estes não codificados:

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

Mas se você espera URLs gerados aleatoriamente, não deve usá-lo .!, porque eles marcam o final de uma frase e alguns aplicativos de email não vinculam automaticamente o último caractere do URL. Exemplo:

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

Abordagem prática - bom trabalho. Estava procurando pela última lista sua - o +sinal especialmente :-D
Oliver

12

A partir daqui

Portanto, apenas alfanuméricos, caracteres especiais $-_.+!*'(), e caracteres reservados usados ​​para fins reservados podem ser usados ​​não codificados em um URL.



5

O RFC3986 define dois conjuntos de caracteres que você pode usar em um URI:

  • Caracteres reservados ::/?#[]@!$&'()*+,;=

    reservado = delimitações genéricas / sublimites

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

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

    O objetivo dos caracteres reservados é fornecer um conjunto de caracteres delimitadores que sejam distinguíveis de outros dados em um URI. URIs que diferem na substituição de um caractere reservado pelo seu octeto codificado em porcentagem correspondente não são equivalentes.

  • Caracteres não reservados :A-Za-z0-9-_.~

    não reservado = ALPHA / DIGIT / "-" / "." / "_" / "~"

    Os caracteres permitidos em um URI, mas que não têm um objetivo reservado, são chamados de não reservados.


3

A próxima mudança é para nomes de domínio em árabe e chinês, não URIs. Os URIs internacionalizados são chamados IRIs e são definidos na RFC 3987 . No entanto, tendo dito que eu recomendaria não fazer isso sozinho, contando com uma biblioteca já testada, já que existem muitas opções de codificação / decodificação de URI e o que é considerado seguro por especificação, versus o que é seguro pelo uso real (navegadores) .


0

Se você deseja dar um tipo especial de experiência aos usuários, pode usar pushStateuma variedade de caracteres para o URL do navegador:

insira a descrição da imagem aqui

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);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.