Caracteres permitidos en una URL

191

¿Alguien sabe la lista completa de caracteres que se pueden usar dentro de un GET sin codificar? En este momento estoy usando AZ az y 0-9 ... pero estoy buscando encontrar la lista completa.

También me interesa saber si hay una especificación publicada para la próxima incorporación de URLs chinas y árabes (ya que obviamente eso tendrá un gran impacto en mi pregunta)

marca
fuente
55
Los caracteres permitidos en un URI son reservados !*'();:@&=+$,/?#[]o no reservados A-Za-z0-9_.~-(o un carácter de porcentaje %como parte de una codificación de porcentaje)
Mikl
1
En MySQL, uso esto REGEXP '[^]A-Za-z0-9_.~!*''();:@&=+$,/?#[%-]+'para encontrar cadenas de URL con caracteres incorrectos. Quizás también sea útil para alguien más.
Mikl
@Mikl: Esa cosa apenas parece una expresión regular.
Jens Mander

Respuestas:

182

De la especificación RFC 1738 :

Por lo tanto, solo los caracteres alfanuméricos, los caracteres especiales " $-_.+!*'()," y los caracteres reservados utilizados para sus fines reservados pueden utilizarse sin codificar dentro de una URL.

EDITAR: Como @Jukka K. Korpela señala correctamente, este RFC fue actualizado por RFC 3986 . Esto ha ampliado y aclarado los caracteres válidos para el host, desafortunadamente no es fácil de copiar y pegar, pero haré lo mejor que pueda.

En el primer orden coincidente:

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
Myles
fuente
55
@Tim slash es un carácter reservado, por lo tanto, si se usa para su propósito reservado (delinear rutas, delinear protocolos ...), entonces no necesita escapar. De lo contrario, lo hace.
Myles
44
Las reglas genéricas de sintaxis de RFC 1738 quedaron obsoletas en 1998.
Jukka K. Korpela
3
@Myles, STD 66 (= RFC 3986) se menciona en otras respuestas. Si el contenido de las respuestas es correcto es un tema diferente; No creo que ninguna de las respuestas describa correctamente la lista completa.
Jukka K. Korpela
44
Y puede agregar una lista de A-Za-z0-9_.-~caracteres no reservados y reservados al comienzo de esta respuesta. !*'();:@&=+$,/?#[]Puede ahorrar tiempo para las personas
Mikl
2
@basZero Lamento que lo hayas encontrado confuso, pero la respuesta completa no es simple. La respuesta a su pregunta es no, ya que es un carácter reservado según lo establecido por:reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
Myles
42

Los caracteres permitidos en un URI son reservados o no reservados (o un carácter de porcentaje como parte de una codificación de porcentaje)

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

dice que estos son RFC 3986 caracteres no reservados (sec. 2.3), así como los caracteres reservados (sec 2.2) si que necesitan para conservar su significado especial. Y también un carácter de porcentaje como parte de una codificación de porcentaje.

Ámbar
fuente
77
Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden volverse inválidas si la página vinculada cambia.
jaestevan
@jaestevan Cita del 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

La lista completa de los 66 caracteres no reservados se encuentra en RFC3986, aquí: http://tools.ietf.org/html/rfc3986#section-2.3

Este es cualquier carácter en el siguiente conjunto de expresiones regulares:

[A-Za-z0-9_.\-~]
pizarroso
fuente
2
Puedes usar los reservados también.
Qwerty
El obsoleto RFC1738 aparece {}^\~y backtickno es seguro. Y RFC3986 enumera \ como inseguro debido al sistema de archivos. Esto significa que también {}^podría usarse.
mgutt
Entonces, si está intentando, por ejemplo, encontrar el final de una url dentro de una cadena (que yo soy), sería mejor seguir los estándares obsoletos en la respuesta aceptada ... Si está validando las url, debería usa el conjunto de caracteres en esta respuesta.
ashleedawg
Cuidado, has escrito esto como una clase de caracteres de expresión regular. Asegúrese de escapar -o ponerlo al principio o al final de la clase de caracteres, porque en [.-~]realidad contiene todos los caracteres ASCII del 46 al 126.
kwl
19

Lo probé solicitando mi sitio web (apache) con todos los caracteres disponibles en mi teclado alemán como parámetro de URL:

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

Estos no fueron codificados:

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

No codificado después de urlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

No codificado después de rawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

Nota: Antes de PHP 5.3.0 rawurlencode()codificado ~debido a RFC 1738 . Pero esto fue reemplazado por RFC 3986, por lo que ahora es seguro de usar. Pero no entiendo por qué, por ejemplo, {}están codificados rawurlencode()porque no se mencionan en RFC 3986.

Una prueba adicional que hice fue con respecto a la vinculación automática en los mensajes de correo. Probé Mozilla Thunderbird, aol.com, outlook.com, gmail.com, gmx.de y yahoo.de y vincularon completamente las URL que contienen estos caracteres:

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

Por supuesto ?, también estaba vinculado, pero solo si se usó una vez.

Algunas personas ahora sugerirían usar solo los rawurlencode()caracteres, pero ¿alguna vez escuchó que alguien tuvo problemas para abrir estos sitios web?

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

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

Además
https://plus.google.com/+google

Al firmar, Colón, coma y signo de exclamación
https: //www.google.com/maps/place/USA/@36.2218457, ...

Debido a eso, estos caracteres deberían poder utilizarse sin codificar sin problemas. Por supuesto, no debe usarlo &;debido a secuencias de codificación como &amp;. La misma razón es válida %ya que solía codificar caracteres en general. Y a =medida que asigna un valor a un nombre de parámetro.

Finalmente, diría que está bien usar estos sin codificar:

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

Pero si espera URL generadas aleatoriamente que no debe usar .!, porque marcan el final de una oración y algunas aplicaciones de correo no vincularán automáticamente el último carácter de la URL. Ejemplo:

Visit http://example.com/foo=bar! !
mgutt
fuente
Enfoque práctico: buen trabajo. Estaba buscando esa última lista tuya, +especialmente el letrero :-D
Oliver
12

Desde aqui

Por lo tanto, solo los caracteres alfanuméricos, los caracteres especiales $-_.+!*'(), y los caracteres reservados utilizados para sus fines reservados pueden utilizarse sin codificar dentro de una URL.

AdaTheDev
fuente
6

RFC3986 define dos conjuntos de caracteres que puede usar en un URI:

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

    reservado = gen-delims / sub-delims

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

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

    El propósito de los caracteres reservados es proporcionar un conjunto de caracteres delimitadores que se distinguen de otros datos dentro de un URI. Los URI que difieren en el reemplazo de un carácter reservado con su correspondiente octeto codificado en porcentaje no son equivalentes.

  • Personajes no reservados :A-Za-z0-9-_.~

    sin reservas = ALFA / DÍGITO / "-" / "." / "_" / "~"

    Los caracteres que están permitidos en un URI pero que no tienen un propósito reservado se denominan sin reservar.

Cyker
fuente
3

El próximo cambio es para nombres de dominio chinos y árabes, no URI. Los URI internacionalizados se denominan IRI y se definen en RFC 3987 . Sin embargo, habiendo dicho que recomendaría no hacerlo usted mismo, sino confiar en una biblioteca ya probada, ya que hay muchas opciones de codificación / decodificación de URI y lo que se considera seguro por especificación, frente a lo que es seguro por uso real (navegadores) .

dajobe
fuente
0

Si desea brindar un tipo especial de experiencia a los usuarios, puede utilizar pushStatepara llevar una amplia gama de caracteres a la URL del navegador:

ingrese la descripción de la imagen aquí

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);
Severo
fuente