validation - validacion - ¿Qué caracteres hacen que una URL no sea válida?
validar formulario php antes enviar (10)
En general, los URI definidos por RFC 3986 (consulte la Sección 2: Caracteres ) pueden contener cualquiera de los siguientes caracteres:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&''()*+,;=
Tenga en cuenta que esta lista no indica dónde pueden aparecer estos caracteres en la URI.
Cualquier otro carácter debe codificarse con el porcentaje de codificación ( %
hh
). Cada parte del URI tiene restricciones adicionales sobre qué caracteres deben representarse con una palabra codificada en porcentaje.
¿Qué caracteres hacen que una URL no sea válida?
¿Son estas URL válidas?
example.com/file[/].html
-
http://example.com/file[/].html
En su pregunta complementaria, usted 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 pretendía preguntar si http://www.example.com/file[/].html
es una URL válida, la respuesta sigue siendo no porque los caracteres de corchete no son válidos allí.
Los caracteres del corchete se reservan para las 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 el RFC 3986 con cuidado si quiere comprender el problema completamente.
La mayoría de las respuestas existentes aquí no son prácticas porque ignoran totalmente el uso en el mundo real de direcciones como:
Bien, según RFC 3986 , estas direcciones no son URI (y, por lo tanto, no son URL, ya que las URL son un tipo de URI ). Si nos consideramos obligados a cumplir con la terminología de los estándares IETF existentes, entonces deberíamos llamarlos IRI (Identificadores de recursos internacionalizados), como se define en RFC 3987 , que técnicamente no son URI pero que pueden convertirse en URI simplemente por porcentaje de codificación. -ASCII caracteres en el IRI. Sin embargo, las personas normales nunca han oído hablar de IRI y simplemente llaman a estos URI o URL (y de hecho hay un esfuerzo WHATWG en curso para crear una nueva especificación de URL más amplia que simplemente clasifique todos los "URI" y "IRI" como "URL" para alinear con el uso moderno de esos términos en el mundo real).
Supongamos que queremos adoptar este significado de URL inmediatamente (lo que pone en desacuerdo con la especificación IETF, pero nos alinea con el uso diario). En ese caso, ¿qué caracteres son válidos en una URL?
En primer lugar, tenemos dos tipos de reserved RFC 3986:
-
:/?#[]@
, que forman parte de la sintaxis genérica para 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 de URI particulares. Por ejemplo, los puntos y comas se usan como parte de la sintaxis de los URI de datos , y&
y=
se usan como parte del formato ubicuo?foo=bar&qux=baz
en las cadenas de consulta (que no está especificado por RFC 3986).
Cualquiera de los caracteres reservados anteriormente se puede usar legalmente en una URI sin codificación, ya sea para cumplir su propósito sintáctico o simplemente como caracteres literales en los datos en algunos lugares donde tal uso no se podría interpretar erróneamente como el carácter que cumple su propósito sintáctico. (Por ejemplo, aunque /
tiene un 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 %
sí mismo se permite para codificaciones en porcentaje.
Eso deja solo los siguientes caracteres ASCII que tienen prohibido aparecer en una URL:
- Los caracteres de control (caracteres 0-1F y 7F), que incluyen nueva línea, pestaña y retorno de carro.
-
"<>/^`{|}
Todos los demás caracteres de ASCII pueden aparecer legalmente en una URL.
Luego, RFC 3987 extiende 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
Pero esas opciones de bloque parecen extrañas y arbitrarias dadas las últimas definiciones de bloque de Unicode; esto es probablemente porque los bloques se han agregado en la década desde que se escribió RFC 3987. La especificación en curso de WhatWG tiene una lista más generosa :
U + 00A0 a U + D7FF, U + E000 a U + FDCF, U + FDF0 a U + FFFD, U + 10000 a U + 1FFFD, U + 20000 a U + 2FFFD, U + 30000 a U + 3FFFD, U + 40000 a U + 4FFFD, U + 50000 a U + 5FFFD, U + 60000 a U + 6FFFD, U + 70000 a U + 7FFFD, U + 80000 a U + 8FFFD, U + 90000 a U + 9FFFD, U + A0000 a U + AFFFD, U + B0000 a U + BFFFD, U + C0000 a U + CFFFD, U + D0000 a U + DFFFD, U + E0000 a U + EFFFD, U + F0000 a U + FFFFD, U + 100000 a U + 10FFFD
Por supuesto, se debe tener en cuenta que el simple hecho de saber qué caracteres pueden aparecer legalmente en una URL no es suficiente para reconocer si una cadena dada es una URL legal o no, ya que algunos caracteres solo son legales en determinadas partes 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 tanto, el ejemplo de OP de http://example.com/file[/].html
es ilegal.
Necesito seleccionar un carácter para dividir las URL en una cadena, así que decidí crear una lista de caracteres que no puedo encontrar en la URL por mi cuenta:
>>> allowed = "-_.~!*''();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
>>> from string import printable
>>> ''''.join(set(printable).difference(set(allowed)))
''`" </x0b/n/r/x0c///t{^}|>''
Por lo tanto, las opciones posibles son la nueva línea, la pestaña, el espacio, la barra invertida y "<>{}^|
. Creo que iré con el espacio o la nueva línea. :)
No es realmente una respuesta a su pregunta, pero la validación de las URL es realmente una pita seria. Probablemente sea mejor validar el nombre de dominio y dejar que la consulta sea parte de la URL. Esa es mi experiencia. También puede recurrir a hacer ping a la URL y ver si da como resultado una respuesta válida, pero eso podría ser demasiado para una tarea tan simple.
Las expresiones regulares para detectar url son abundantes, google :)
Para agregar algunas aclaraciones y abordar directamente la pregunta anterior, hay varias clases de caracteres que causan problemas para las URL y los URI.
Hay algunos caracteres que no están permitidos y nunca deben aparecer en una URL / URI, caracteres reservados (descritos a continuación) y otros caracteres que pueden causar problemas en algunos casos, pero están marcados como "imprudentes" o "inseguros". Las explicaciones de por qué los caracteres están restringidos se explican claramente en RFC-1738 (URL) y RFC-2396 (URI). Tenga en cuenta que el nuevo RFC-3986 (actualización a RFC-1738) define la construcción de los caracteres permitidos en un contexto dado, pero la especificación anterior ofrece una descripción más simple y más general de qué caracteres no están permitidos con las siguientes reglas.
Se excluyen los caracteres US-ASCII 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 = "<" | ">" | "#" | "%" | <">
La lista de caracteres imprudentes está permitida pero puede causar problemas:
unwise = "{" | "}" | "|" | "/" | "^" | "[" | "]" | "`"
Los caracteres que están reserved 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 URI genérica. Los caracteres en el 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 como ftp://user@hostname/
donde el carácter ''@'' tiene un significado especial.
Este es un ejemplo de una URL que tiene caracteres no válidos e imprudentes (por ejemplo, ''$'', ''['', '']'') y debe estar correctamente codificada:
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 los URI / URL dependen del lenguaje de programación. Por ejemplo, el ''|'' El carácter (0x7C) aunque solo esté marcado como "imprudente" en la especificación URI lanzará una URISyntaxException en el constructor Java java.net.URI, por lo que una URL como http://api.google.com/q?exp=a|b
es no permitido y debe estar codificado en su lugar como http://api.google.com/q?exp=a%7Cb
si se utiliza Java con una instancia de objeto URI.
Se me ocurrió un par de expresiones regulares para PHP que convertirán las URL en texto para anclar etiquetas. (Primero, convierte todos los www. Urls a http: // y luego todos los urls con https?: // a href = ... html links
$string = preg_replace(''/(https?:////)([!#$&-;=?/-/[/]_a-z~%]+)/sim'', ''<a href="$1$2">$2</a>'', preg_replace(''/(/s)((www/.)([!#$&-;=?/-/[/]_a-z~%]+))/sim'', ''$1http://$2'', $string) );
Todos los caracteres válidos que se pueden usar en un URI (una URL es un tipo de URI ) se definen en RFC-3986 .
Todos los demás caracteres se pueden usar en una URL siempre que estén "codificados por URL" primero. Esto implica cambiar el carácter no válido para "códigos" específicos (generalmente en la forma del símbolo de porcentaje (%) seguido de un número hexadecimal).
Este enlace, Referencia de codificación de URL de HTML , contiene una lista de las codificaciones de caracteres no válidos.
Use urlencode para permitir caracteres arbitrarios en su URL.
Varios de los rangos de caracteres de Unicode son HTML5 válidos , aunque podría no ser una buena idea usarlos.
Por ejemplo, los documentos href
dicen http://www.w3.org/TR/html5/links.html#attr-hyperlink-href :
El atributo href en los elementos de área y debe tener un valor que sea una URL válida potencialmente rodeada por espacios.
Luego, la definición de "URL válida" apunta a http://url.spec.whatwg.org/ , que dice que apunta a:
Alinee RFC 3986 y RFC 3987 con implementaciones contemporáneas y desactívelas en el proceso.
Ese documento define los puntos de código URL como:
ASCII alfanumérico, "!", "$", "&", "''", "(", ")", "*", "+", ",", "-", ".", "/" , ":", ";", "=", "?", "@", "_", "~" y puntos de código en los rangos U + 00A0 a U + D7FF, U + E000 a U + FDCF , U + FDF0 a U + FFFD, U + 10000 a U + 1FFFD, U + 20000 a U + 2FFFD, U + 30000 a U + 3FFFD, U + 40000 a U + 4FFFD, U + 50000 a U + 5FFFD, U +60000 a U + 6FFFD, U + 70000 a U + 7FFFD, U + 80000 a U + 8FFFD, U + 90000 a U + 9FFFD, U + A0000 a U + AFFFD, U + B0000 a U + BFFFD, U + C0000 a U + CFFFD, U + D0000 a U + DFFFD, U + E1000 a U + EFFFD, U + F0000 a U + FFFFD, U + 100000 a U + 10FFFD.
El término "puntos de código URL" se usa en la declaración:
Si c no es un punto de código URL y no es "%", parse error.
en varias partes del algoritmo de análisis, incluidos el esquema, la autoridad, la ruta relativa, la consulta y los estados de fragmentos: básicamente toda la URL.
Además, el validador http://validator.w3.org/ pasa por URL como "你好"
, y no pasa por URL con caracteres como espacios "ab"
Por supuesto, como lo mencionó Stephen C, no se trata solo de los caracteres sino también del contexto: hay que entender todo el algoritmo. Pero como la clase de "puntos de código URL" se usa en puntos clave del algoritmo, da una buena idea de lo que puede usar o no.
Ver también: caracteres Unicode en URLs.