602 votes

Quels caractères rendent une URL invalide ?

Quels caractères rendent une URL invalide?

Ces URL sont-elles valides?

  • example.com/file[/].html
  • http://example.com/file[/].html

52 votes

Lors de la validation, vous devez toujours "penser positif" : demander "ce qui est valide", tout le reste est invalide. Tester contre les (quelques) caractères valides est beaucoup plus sûr (et plus facile !) que tous les caractères invalides possibles.

671voto

Gumbo Points 279147

En général, les URIs telles que définies par RFC 3986 (voir Section 2 : Caractères) peuvent contenir l'un des 84 caractères suivants :

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=

Notez que cette liste ne précise pas où dans l'URI ces caractères peuvent apparaître.

Tout autre caractère doit être encodé avec l'encodage en pourcentage (%hh). Chaque partie de l'URI comporte des restrictions supplémentaires sur les caractères qui doivent être représentés par un mot encodé en pourcentage.

39 votes

(bien sûr, la liste de caractères ne précise pas dans l'URL ils peuvent apparaître)

2 votes

@Eamon Nerbonne: Oui, il s'agit uniquement de l'union des ensembles de caractères valides de tous les composants.

82 votes

Voici une regex qui déterminera si l'ensemble de la chaîne contient uniquement les caractères ci-dessus: /^[!#$&-;=?-[]_a-z~]+$/

244voto

JasonM1 Points 2711

Le '[' et ']' dans cet exemple sont des caractères "peu judicieux" mais toujours légaux. Si le '/' dans les [] est censé être partie intégrante du nom de fichier alors c'est invalide car '/' est réservé et devrait être correctement encodé :

http://example.com/file[/].html

Pour ajouter quelques clarifications et répondre directement à la question ci-dessus, il y a plusieurs classes de caractères qui posent problème pour les URL et URI.

Il y a certains caractères qui sont interdits et ne doivent 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 considérés comme "peu judicieux" ou "non sécurisés". Les explications sur pourquoi les caractères sont restreints sont clairement énoncées dans RFC-1738 (URLs) et RFC-2396 (URIs). Remarquez que le plus récent RFC-3986 (mise à jour de RFC-1738) définit la construction de quels caractères sont 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 qui ne sont pas autorisés avec les règles suivantes.

Caractères de l'US-ASCII exclus interdits dans la syntaxe de l'URI :

   contrôle     = 
   espace       = 
   délimiteurs  = "<" | ">" | "#" | "%" | <">

Le caractère "#" est exclu car il est utilisé pour délimiter un URI d'un identifiant de fragment. Le caractère pourcent "%" est exclu car il est utilisé pour l'encodage des caractères échappés. En d'autres termes, le "#" et "%" sont des caractères réservés qui doivent être utilisés dans un contexte spécifique.

Liste des caractères peu judicieux autorisés mais pouvant poser problème :

   peu judicieux      = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"

Caractères réservés dans un composant de requête et/ou ayant un signification spéciale dans un URI/URL :

  réservés    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","

La classe de syntaxe "réservés" ci-dessus fait référence à ces caractères qui sont autorisés dans un 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és" 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 être quelque chose comme ftp://user@hostname/ où le caractère '@' a une signification spéciale.

Voici un exemple d'une URL qui contient des caractères invalides et peu judicieux (par ex. '$', '[', ']') et qui devrait être correctement encodée :

http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg

Certaines des restrictions de caractères pour les URIs et URLs dépendent du langage de programmation. Par exemple, le '|' (0x7C) caractère bien qu'étant seulement considéré comme "peu judicieux" dans la spécification de l'URI provoquera 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 être encodée comme http://api.google.com/q?exp=a%7Cb si on utilise Java avec une instance d'objet URI.

2 votes

Excellente, réponse détaillée, la seule à répondre directement à la question réelle. La section réservée peut 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 à aucune de ces listes. Oh, et au lieu de %25 dans la dernière chaîne, ne voulez-vous pas dire %7C?

1 votes

Merci. Bonne observation : 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 depuis RFC-2396.

2 votes

Cette réponse n'est pas mauvaise, mais il y a quelques confusions et erreurs. Vous confondez initialement les caractères non autorisés et les caractères réservés (deux choses très différentes), vous faites trop de différences entre les caractères "non judicieux" et les autres caractères non autorisés (supprimés dans la RFC 3986 et sans importance syntaxique même dans la 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 "dans un composant de requête".

101voto

Stephen C Points 255558

Il ne s'agit pas seulement des caractères utilisés. Différents caractères sont autorisés à différents endroits. Par exemple, selon la RFC 2396, un '?' non échappé est autorisé dans la partie fragment mais pas dans 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, vous devriez lire la RFC 3986.


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 d'un ':'.

Mais Dominic dit ensuite que http://example.com/file[/].html n'est pas une URL valide non plus, 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 doivent encoder en pourcentage les octets de données correspondant aux caractères de l'ensemble réservé, à moins que ces caractères soient spécifiquement autorisés par le schéma URI pour représenter des données dans ce composant."

(Remarque - le mot opérant ici est "devrait", et non "doit" ou "doit". C'est un conseil, pas une prescription.)

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, alors 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érant est "doit". Cela indique ce qu'un URI signifie si quelqu'un ignore le conseil de la phrase précédente.)

Comment cela s'applique-t-il ici? Eh bien, HTTP est un schéma "hiérarchique", et l'ABNF générique pour les schémas hiérarchiques ne dit pas que '[' ou ']' sont des délimiteurs dans un . D'un autre côté, l'ABNF dit que se compose de caractères , , de caractères codés en pourcentage, de ':' ou de '@'. En d'autres termes, '[' ou ']' ne sont pas autorisés par une lecture stricte de l'ABNF.

Donc, strictement parlant, "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 précédente de la spécification dit que les caractères '[' et ']' doivent être traités comme des caractères de données. Ainsi, l'URL serait analysée comme suit:

  • schéma == "http"
  • autorité == "example.com"
  • chemin == "/file[/].html"

Et le chemin devrait être analysé en tant que '/' '/' où le premier segment est "file[" et le deuxième est "].html"

19voto

Dominic Sayers Points 1148

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 une 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, alors la réponse est toujours non car les crochets ne sont pas valides ici.

Les crochets 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 de domaine).

Il est utile de lire attentivement le RFC 3986 si vous voulez comprendre pleinement la question.

0 votes

Après avoir lu le RFC, je suis plus enclin à être d'accord avec l'explication plus détaillée de @Stephen C.

0 votes

Les URL ne sont pas un sous-ensemble des URI. Les balises [ et ] ne sont pas valides pour presque tous les analyseurs d'URI que j'ai vus. Cela m'a réellement posé problème dans le monde réel : stackoverflow.com/questions/11038967/…

0 votes

@AdamGent Les URL sont vraiment un sous-ensemble des URI. La seule différence entre eux est qu'ils décrivent l'emplacement de la ressource - ce qui est une distinction sémantique, pas une distinction syntaxique. Si les analyseurs que vous avez vus et qui se sont définis comme des analyseurs "URI" traitaient différemment les crochets par rapport à ceux qui se définissaient comme des analyseurs "URL", alors c'est purement une coïncidence, et non causé par une différence entre les URL et les URI.

12voto

CraigTP Points 18514

Tous les caractères valides pouvant être utilisés dans un URI (un 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 qu'ils soient d'abord "Encodés en URL". Cela implique de changer le caractère invalide pour des "codes" spécifiques (généralement sous la forme du symbole pourcent (%) suivi d'un nombre hexadécimal).

Ce lien, Référence d'encodage d'URL HTML, contient une liste des encodages pour les caractères invalides.

0 votes

Et pour les caractères Unicode, l'article de Wikipedia Encodage du pourcentage dit ce qui suit : "La syntaxe générique d'URI impose que les nouveaux schémas d'URI permettant la représentation de données de caractères dans un URI doivent, en effet, représenter des caractères de l'ensemble non réservé sans traduction, et doivent convertir tous les autres caractères en octets selon l'UTF-8, puis encoder en pourcentage ces valeurs."

Prograide.com

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.

Powered by:

X