Quels caractères rendent une URL invalide ?
Ces URL sont-elles valides ?
example.com/file[/].html
http://example.com/file[/].html
Quels caractères rendent une URL invalide ?
Ces URL sont-elles valides ?
example.com/file[/].html
http://example.com/file[/].html
En général, les URI telles que définies par RFC 3986 (voir Section 2 : Caractères) peuvent contenir l'un des 84 caractères suivants :
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
Remarque : cette liste ne précise pas où dans l'URI ces caractères peuvent apparaître.
Tout autre caractère doit être encodé avec le codage de pourcentage (%
hh
). Chaque partie de l'URI présente des restrictions supplémentaires quant aux caractères devant être représentés par un mot encodé en pourcentage.
@Eamon Nerbonne : Oui, il s'agit uniquement de l'union des ensembles de caractères valides de tous les composants.
Voici une regex qui déterminera si l'ensemble de la chaîne contient uniquement les caractères ci-dessus : /^[!#$&-;=?-[]_a-z~]+$/
Les caractères '[' et ']' dans cet exemple sont des caractères "imprudents" mais toujours légaux. Si le '/' dans les crochets est censé faire partie du nom de fichier, alors c'est invalide car '/' est réservé et doit être correctement encodé :
http://example.com/file[/].html
Pour ajouter quelques éclaircissements et répondre directement à la question ci-dessus, il existe plusieurs classes de caractères qui posent problème pour les URL et les URIs.
Il y a des caractères qui sont interdits et ne devraient jamais apparaître dans une URL/URI, des caractères réservés (décrits ci-dessous), et d'autres caractères qui peuvent poser problème dans certains cas, mais qui sont marqués comme "imprudents" ou "non sûrs". Les explications sur la raison pour laquelle les caractères sont restreints sont clairement indiquées dans RFC-1738 (URLs) et RFC-2396 (URIs). Notez que le plus récent RFC-3986 (mise à jour de RFC-1738) définit la construction des caractères autorisés dans un contexte donné, mais la spécification plus ancienne offre une description plus simple et plus générale des caractères interdits avec les règles suivantes.
Caractères US-ASCII exclus interdits dans la syntaxe de l'URI :
control =
space =
delims = "<" | ">" | "#" | "%" | <">
Le caractère "#" est exclu car il est utilisé pour délimiter une URI d'un identifiant de fragment. Le caractère pourcentage "%" est exclu car il est utilisé pour l'encodage des caractères échappés. En d'autres termes, "#" et "%" sont des caractères réservés qui doivent être utilisés dans un contexte spécifique.
Liste des caractères imprudents qui sont autorisés mais peuvent poser des problèmes :
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
Caractères qui sont réservés dans un composant de requête et/ou ont une signification spéciale dans une URI/URL :
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
La classe de syntaxe "réservée" ci-dessus se réfère aux caractères autorisés dans une URI, mais qui peuvent ne pas être autorisés dans un composant particulier de la syntaxe générique de l'URI. Les caractères de l'ensemble "réservé" ne sont pas réservés dans tous les contextes. Par exemple, le nom d'hôte peut contenir un nom d'utilisateur optionnel, donc il pourrait ressembler à quelque chose comme ftp://user@hostname/
où le caractère '@' a un sens spécial.
Voici un exemple d'une URL qui contient des caractères invalides et imprudents (par ex. '$', '[', ']') et qui doit être correctement encodée :
http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg
Certaines restrictions de caractères pour les URIs et URLs dépendent du langage de programmation. Par exemple, le caractère '|' (0x7C) bien qu'étant seulement marqué comme "imprudent" dans la spécification de l'URI va générer une URISyntaxException dans le constructeur Java java.net.URI donc une URL comme http://api.google.com/q?exp=a|b
n'est pas autorisée et doit plutôt être encodée comme http://api.google.com/q?exp=a%7Cb
si vous utilisez Java avec une instance d'objet URI.
Excellent, réponse détaillée, la seule à répondre directement à la question réelle. La section réservée pourrait avoir besoin de travail, par exemple, le ?
littéral est très bien dans la section de requête, mais impossible avant cela, et je ne pense pas que @
appartienne dans aucune de ces listes. Oh, et au lieu de %25
dans la dernière chaîne, voulez-vous dire %7C
?
Merci. Belle trouvaille : le %25 était une faute de frappe dans l'exemple. Ajout d'une note de bas de page à la description de la syntaxe "réservée" directement à partir de RFC-2396.
Cette réponse n'est pas mauvaise, mais il y a des confusions et des erreurs. Vous confondez initialement les caractères non autorisés et réservés (choses très différentes), vous faites trop de l'importance de la distinction entre les caractères "peu judicieux" et les autres caractères non autorisés (supprimés dans RFC 3986 et syntaxiquement non pertinents même dans RFC 2396), et vous présentez de manière confuse une liste de tous les caractères réservés comme la liste réservée "à l'intérieur d'un composant de requête".
Il ne s'agit pas seulement des caractères. Différents caractères sont autorisés à différents points. Par exemple, d'après la RFC 2396, un caractère non échappé '?' est autorisé dans la partie fragment mais pas la partie chemin.
Vous devez lire la RFC 2396 pour comprendre les détails ... ou poser une question plus spécifique. Ou si vous voulez vraiment dire URI plutôt que URL, la RFC 3986 est ce que vous devriez lire.
Vous avez demandé si example.com/file[/].html
est une URL valide.
Je suis d'accord avec Dominic Sayers - Non. Une URL doit avoir un schéma explicite, tel que "http", suivi de ':'
.
Mais Dominic affirme ensuite que http://example.com/file[/].html
n'est pas non plus une URL valide, et ce n'est pas si clair.
Les caractères '['
et ']'
sont des caractères et devraient être échappés en pourcentage s'ils ne sont pas utilisés comme délimiteurs dans la syntaxe spécifique au schéma. La spécification dit:
"Les applications produisant des URI devraient encoder en pourcentage les octets de données correspondant à des caractères de l'ensemble réservé à moins que ces caractères ne soient spécifiquement autorisés par le schéma d'URI à représenter des données dans ce composant."
(Note - le mot opératif ici est "should", et non "shall" ou "must". C'est consultatif, pas prescriptif.)
La phrase suivante de la spécification dit ceci:
"Si un caractère réservé est trouvé dans un composant d'URI et aucun rôle de délimitation n'est connu pour ce caractère, il doit être interprété comme représentant l'octet de données correspondant à l'encodage de ce caractère en US-ASCII"
(Notez que le mot opératif est "must". Cela indique ce qu'un URI signifie si quelqu'un ignore les conseils de la phrase précédente.)
Alors comment cela s'applique-t-il ici? Eh bien HTTP est un schéma "hiérarchique", et le ABNF générique pour les schémas hiérarchiques n'indique pas que '['
ou ']'
sont des délimiteurs dans un . En revanche, le ABNF indique qu'un se compose de caractères , de sous-délimiteurs, de caractères échappés en pourcentage, ':'
ou '@'
. En d'autres termes, '['
ou ']'
ne sont pas autorisés par une lecture stricte de l'ABNF.
Donc, strictement "http://example.com/file[/].html"
n'est pas valide. Mais si vous rencontrez une telle URL (et ne décidez pas de la rejeter), la partie antérieure de la spécification indique que les caractères '['
et ']'
doivent être traités comme des caractères de données. Ainsi, l'URL serait analysée comme suit:
"http"
"example.com"
"/file[/].html"
Et le chemin devrait être analysé comme '/' '/'
où le premier segment est "file["
et le deuxième est "].html"
Dans votre question supplémentaire, vous avez demandé si www.example.com/file[/].html
est une URL valide.
Cette URL n'est pas valide car une URL est un type d'URI et un URI valide doit avoir un schéma comme http:
(voir RFC 3986).
Si vous vouliez demander si http://www.example.com/file[/].html
est une URL valide, la réponse est toujours non car les caractères de crochet ne sont pas valides ici.
Les caractères de crochet sont réservés pour les URLs dans ce format : http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(c'est-à-dire une adresse IPv6 littérale au lieu d'un nom d'hôte)
Il est utile de lire attentivement le RFC 3986 si vous souhaitez bien comprendre le problème.
Après avoir lu le RFC, je suis plus enclin à être d'accord avec l'explication plus détaillée de @Stephen C.
Les URL ne sont pas un sous-ensemble des URI. Les [
et ]
ne sont pas valides pour presque tous les analyseurs d'URI que j'ai vus. Cela m'a réellement causé des problèmes dans le monde réel : stackoverflow.com/questions/11038967/…
@AdamGent Les URL sont en fait un sous-ensemble des URI. La seule différence entre eux est la manière dont ils décrivent l'emplacement de la ressource, ce qui est une distinction sémantique et non syntaxique. Si les analyseurs que vous avez vus étiquetés comme des analyseurs "URI" traitaient différemment les crochets par rapport à ceux étiquetés comme des analyseurs "URL", alors c'est pure coïncidence, et non causé par une différence entre les URL et les URI.
Tous les caractères valides pouvant être utilisés dans une URI (une URL est un type d'URI) sont définis dans RFC 3986.
Tous les autres caractères peuvent être utilisés dans une URL à condition d'être préalablement "encodés en URL". Cela consiste à remplacer le caractère invalide par des "codes" spécifiques (généralement sous forme du symbole pour cent (%) suivi d'un nombre hexadécimal).
Ce lien, Référence de codage d'URL HTML, contient une liste des encodages pour les caractères invalides.
Et pour les caractères Unicode, l'article de Wikipedia Encodage en pourcentage dit ce qui suit: "La syntaxe générique de l'URI exige que les nouveaux schémas d'URI qui permettent la représentation de données de caractères dans un URI doivent, en effet, représenter des caractères de l'ensemble sans traduction, et convertir tous les autres caractères en octets selon UTF-8, puis encoder en pourcentage ces valeurs."
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
52 votes
Lors de la validation, vous devriez toujours "penser positif" : demandez "ce qui est valide", tout le reste est invalide. Tester avec les (quelques) caractères valides est beaucoup plus sûr (et plus facile !) que tous les caractères invalides possibles.
2 votes
Connexe : Quelle est la meilleure expression régulière pour vérifier si une chaîne est une URL valide ?