¿Qué caracteres invalidan una URL?
¿Qué caracteres invalidan una URL?
¿Son estas URL válidas?
example.com/file[/].html
http://example.com/file[/].html
En general, los URI definidos por RFC 3986 (consulte la Sección 2: Caracteres ) pueden contener cualquiera de los siguientes 84 caracteres:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
Tenga en cuenta que esta lista no indica en qué parte del URI pueden aparecer estos caracteres.
Cualquier otro carácter debe codificarse con la codificación porcentual ( %
hh
). Cada parte del URI tiene restricciones adicionales sobre qué caracteres deben representarse mediante una palabra codificada por porcentaje.
Los '[' y ']' en este ejemplo son caracteres "imprudentes" pero aún así son legales. Si '/' en [] está destinado a ser parte del nombre del archivo, entonces no es válido ya que '/' está reservado y debe codificarse correctamente:
http://example.com/file[/].html
Para agregar algunas aclaraciones y abordar directamente la pregunta anterior, existen varias clases de caracteres que causan problemas para las URL y URI.
Hay algunos caracteres que no están permitidos y nunca deberían aparecer en una URL/URI, caracteres reservados (descritos a continuación) y otros caracteres que pueden causar problemas en algunos casos, pero que están marcados como "imprudentes" o "inseguros". Las explicaciones de por qué los caracteres están restringidos se detallan claramente en RFC-1738 (URL) y RFC-2396 (URI). Tenga en cuenta que el RFC-3986 más nuevo (actualización de RFC-1738) define la construcción de qué caracteres están permitidos en un contexto determinado, pero la especificación anterior ofrece una descripción más simple y general de qué caracteres no están permitidos con las siguientes reglas.
Caracteres US-ASCII excluidos no permitidos dentro de la sintaxis de URI:
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space = <US-ASCII coded character 20 hexadecimal>
delims = "<" | ">" | "#" | "%" | <">
El carácter "#" está excluido porque se utiliza para delimitar un URI de un identificador de fragmento. El carácter de porcentaje "%" se excluye porque se utiliza para codificar caracteres de escape. En otras palabras, "#" y "%" son caracteres reservados que deben usarse en un contexto específico.
Se permiten una lista de caracteres imprudentes, pero pueden causar problemas:
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
Caracteres que están reservados dentro de un componente de consulta y/o tienen un significado especial dentro de un URI/URL:
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
La clase de sintaxis "reservada" anterior se refiere a aquellos caracteres que están permitidos dentro de un URI, pero que pueden no estar permitidos dentro de un componente particular de la sintaxis genérica de URI. Los caracteres del conjunto "reservado" no están reservados en todos los contextos . El nombre de host, por ejemplo, puede contener un nombre de usuario opcional, por lo que podría ser algo así como ftp://user@hostname/
donde el carácter '@' tiene un significado especial.
A continuación se muestra un ejemplo de una URL que tiene caracteres no válidos e imprudentes (por ejemplo, '$', '[', ']') y debe codificarse correctamente:
http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg
Algunas de las restricciones de caracteres para URI y URL dependen del lenguaje de programación. Por ejemplo, el '|' (0x7C), aunque solo está marcado como "imprudente" en la especificación de URI, generará una URISyntaxException en el constructor Java java.net.URI , por lo que una URL como http://api.google.com/q?exp=a|b
no está permitida y debe codificarse como http://api.google.com/q?exp=a%7Cb
si se usara Java con una instancia de objeto URI.
La mayoría de las respuestas existentes aquí no son prácticas porque ignoran por completo el uso real de direcciones como:
- https://en.wikipedia.org/wiki/Möbius_strip o
- https://zh.wikipedia.org/wiki/Wikipedia:关于中文维基百科/en .
Primero, una digresión en la terminología. ¿ Cuáles son estas direcciones? ¿Son URL válidas?
Históricamente, la respuesta fue "no". Según RFC 3986 , de 2005, dichas direcciones no son URI (y por lo tanto no son URL, ya que las URL son un tipo de URI ). Según la terminología de los estándares IETF de 2005, deberíamos llamarlos correctamente IRI (Identificadores de recursos internacionalizados), como se define en RFC 3987 , que técnicamente no son URI, pero pueden convertirse en URI simplemente codificando porcentualmente todos los caracteres no ASCII en el IRI. .
Según las especificaciones modernas, la respuesta es "sí". El WHATWG Living Standard simplemente clasifica todo lo que anteriormente se llamaría "URI" o "IRI" como "URL". Esto alinea la terminología especificada con la forma en que las personas normales que no han leído la especificación usan la palabra "URL", que era uno de los objetivos de la especificación .
¿Qué caracteres están permitidos según el estándar de vida WHATWG?
Según este nuevo significado de "URL", ¿qué caracteres están permitidos? En muchas partes de la URL, como la cadena de consulta y la ruta, podemos usar "unidades de URL" arbitrarias , que son
Puntos de código URL y bytes codificados en porcentaje .
¿Qué son los "puntos de código URL"?
Los puntos del código URL son ASCII alfanuméricos, U+0021 (!), U+0024 ($), U+0026 (&), U+0027 ('), U+0028 PARÉNTESIS IZQUIERDO, U+0029 PARÉNTESIS DERECHO, U+ 002A (*), U+002B (+), U+002C (,), U+002D (-), U+002E (.), U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+003F (?), U+0040 (@), U+005F (_), U+007E (~) y puntos de código en el rango U+00A0 a U +10FFFD, inclusive, excluyendo sustitutos y no personajes.
(Tenga en cuenta que la lista de "puntos de código URL" no incluye %
, pero %
se permiten en "unidades de código URL" si forman parte de una secuencia de codificación porcentual).
El único lugar donde puedo detectar donde la especificación permite el uso de cualquier carácter que no esté en este conjunto es en el host , donde las direcciones IPv6 están encerradas entre caracteres [
y ]
. En el resto de la URL, se permiten unidades de URL o algún conjunto de caracteres aún más restrictivo.
¿Qué caracteres estaban permitidos en los antiguos RFC?
Por el bien de la historia, y dado que no se explora completamente en otras partes de las respuestas aquí, examinemos que se permitió según el par de especificaciones anteriores.
En primer lugar, tenemos dos tipos de caracteres reservados RFC 3986 :
:/?#[]@
, que forman parte de la sintaxis genérica de un URI definido en RFC 3986!$&'()*+,;=
, que no forman parte de la sintaxis genérica del RFC, pero están reservados para su uso como componentes sintácticos de esquemas URI particulares. Por ejemplo, los puntos y comas se utilizan como parte de la sintaxis de los URI de datos&
y se=
utilizan como parte del?foo=bar&qux=baz
formato omnipresente en las cadenas de consulta (que no está especificado en RFC 3986).
Cualquiera de los caracteres reservados anteriores se puede usar legalmente en un URI sin codificación, ya sea para cumplir su propósito sintáctico o simplemente como caracteres literales en datos en algunos lugares donde dicho uso no pueda malinterpretarse como el carácter que cumple su propósito sintáctico. (Por ejemplo, aunque /
tiene significado sintáctico en una URL, puede usarlo sin codificar en una cadena de consulta, porque no tiene significado en una cadena de consulta).
RFC 3986 también especifica algunos caracteres no reservados , que siempre se pueden usar simplemente para representar datos sin ninguna codificación:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
Finalmente, el %
carácter en sí está permitido para codificaciones porcentuales.
Eso deja solo los siguientes caracteres ASCII que tienen prohibido aparecer en una URL:
- Los caracteres de control (caracteres 0-1F y 7F), incluida la nueva línea, la tabulación y el retorno de carro.
"<>^`{|}
Cualquier otro carácter de ASCII puede aparecer legalmente en una URL.
Luego, RFC 3987 amplía ese conjunto de caracteres no reservados con los siguientes rangos de caracteres Unicode:
%xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
/ %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
/ %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
/ %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
/ %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
/ %xD0000-DFFFD / %xE1000-EFFFD
Estas opciones de bloques de la antigua especificación parecen extrañas y arbitrarias dadas las últimas definiciones de bloques Unicode ; Esto probablemente se deba a que los bloques se han agregado en la década desde que se escribió RFC 3987.
Finalmente, quizás valga la pena señalar que simplemente saber qué caracteres pueden aparecer legalmente en una URL no es suficiente para reconocer si una cadena determinada es una URL legal o no, ya que algunos caracteres solo son legales en partes particulares de la URL. Por ejemplo, los caracteres reservados [
y ]
son legales como parte de un host literal IPv6 en una URL como http://[1080::8:800:200C:417A]/foo pero no son legales en ningún otro contexto, por lo que El ejemplo de OP http://example.com/file[/].html
es ilegal.
En su pregunta complementaria, preguntó si www.example.com/file[/].html
es una URL válida.
Esa URL no es válida porque una URL es un tipo de URI y una URI válida debe tener un esquema como http:
(consulte RFC 3986 ).
Si quería preguntar si http://www.example.com/file[/].html
es una URL válida, la respuesta sigue siendo no porque los caracteres entre corchetes no son válidos allí.
Los caracteres entre corchetes están reservados para URL en este formato: http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(es decir, un literal IPv6 en lugar de un nombre de host)
Vale la pena leer detenidamente el RFC 3986 si desea comprender el problema en su totalidad.
Todos los caracteres válidos que se pueden utilizar en un URI (una URL es un tipo de URI ) se definen en RFC 3986 .
Todos los demás caracteres se pueden utilizar en una URL siempre que estén "codificados en URL" primero. Esto implica cambiar el carácter no válido para "códigos" específicos (generalmente en forma de símbolo de porcentaje (%) seguido de un número hexadecimal).
Este enlace, Referencia de codificación de URL HTML , contiene una lista de codificaciones para caracteres no válidos.