Question 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

422
2017-10-10 13:10


origine


Réponses:


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

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

Notez que cette liste n'indique pas où dans l'URI ces caractères peuvent se produire.

Tout autre caractère doit être codé avec le codage en pourcentage (%hh). Chaque partie de l'URI a d'autres restrictions concernant les caractères qui doivent être représentés par un mot codé en pourcentage.


513
2017-10-10 13:26



Pour apporter des précisions et répondre directement à la question ci-dessus, il existe plusieurs classes de caractères qui posent problème pour les URL et les URI.

Certains caractères 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 susceptibles de poser problème dans certains cas, mais marqués comme "imprudents" ou "dangereux". Les explications expliquant pourquoi les caractères sont restreints sont clairement expliquées dans RFC-1738 (URL) et RFC-2396 (URIs). Notez 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 générale plus simple des caractères qui ne sont pas autorisés.

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

   control     = <US-ASCII coded characters 00-1F and 7F hexadecimal>
   space       = <US-ASCII coded character 20 hexadecimal>
   delims      = "<" | ">" | "#" | "%" | <">

La liste des caractères imprudents est autorisée mais peut causer des problèmes:

   unwise      = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"

Les caractères suivants sont réservés dans un composant de requête et ont une signification particulière dans un URI / URL:

  reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","

La classe de syntaxe "réservée" ci-dessus fait référence aux caractères autorisés dans un URI, mais qui peuvent ne pas être autorisés dans un composant particulier de la syntaxe d'URI générique. Les caractères de l'ensemble "réservé" ne sont pas réservés dans tous les contextes. Le nom d’hôte, par exemple, peut contenir un nom d’utilisateur facultatif pour ftp://user@hostname/ où le caractère '@' a une signification particulière.

Voici un exemple d'URL comportant des caractères non valides et non judicieux (par exemple, "$", "[", "]") et devant être correctement codés:

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 URI / URL dépendent du langage de programmation. Par exemple, le '|' (0x7C) caractère bien que seulement marqué comme "imprudent" dans la spécification URI va jeter un URISyntaxException dans le Java java.net.URI constructeur donc une URL comme http://api.google.com/q?exp=a|b n'est pas autorisé et doit être encodé à la place http://api.google.com/q?exp=a%7Cb si vous utilisez Java avec une instance d'objet URI.


137
2017-11-21 18:50



La plupart des réponses existantes sont impraticables car elles ignorent totalement l'utilisation réelle des adresses comme:

OK, donc selon RFC 3986, ces adresses ne sont pas des URI (et donc pas des URL, puisque les URL sont un type d'URI). Si nous nous considérons comme redevables à la terminologie des normes IETF existantes, alors nous devrions les appeler correctement IRI (Internationalized Resource Identifiers), comme défini dans RFC 3987, qui ne sont techniquement pas des URI mais peuvent être convertis en URI simplement en codant en pourcentage tous les caractères non-ASCII de l'IRI. Les gens normaux, cependant, n'ont jamais entendu parler des IRI et appellent simplement ces URI ou URLs (et en effet il y a un WHATWG effort en cours pour créer une nouvelle spécification d'URL plus large qui classe simplement tous les "URI" et "IRI" comme des "URL" pour s'aligner sur l'utilisation moderne de ces termes dans le monde réel).

Supposons que nous voulions adopter cette signification de l'URL immédiatement (ce qui met en contradiction avec les spécifications de l'IETF, mais nous aligne avec l'utilisation quotidienne). Dans ce cas, quels caractères sont valides dans une URL?

Tout d'abord, nous avons deux types de RFC 3986 caractères réservés:

  • :/?#[]@, qui font partie de la syntaxe générique pour un URI défini dans la RFC 3986
  • !$&'()*+,;=, qui ne font pas partie de la syntaxe générique du RFC, mais sont réservés pour être utilisés comme composants syntaxiques de schémas d'URI particuliers. Par exemple, les points-virgules et les virgules sont utilisés dans le cadre de la syntaxe de URI de données, et & et = sont utilisés dans le cadre de l'omniprésente ?foo=bar&qux=baz formatage dans les chaînes de requête n'est pas spécifié par RFC 3986).

N'importe lequel des caractères réservés ci-dessus peut être légalement utilisé dans un URI sans codage, soit pour servir leur but syntaxique, soit simplement comme caractères littéraux dans des données dans certains endroits où une telle utilisation ne peut être interprétée comme le caractère servant son but syntaxique. (Par exemple, bien que / a une signification syntaxique dans une URL, vous pouvez l'utiliser sans coder dans une chaîne de requête, car ne pas avoir un sens dans une chaîne de requête.)

La RFC 3986 spécifie également certains non réservé caractères, qui peuvent toujours être utilisés simplement pour représenter des données sans aucun encodage:

  • abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~

Finalement, le % Le caractère lui-même est autorisé pour les encodages en pourcentage.

Cela ne laisse que les caractères ASCII suivants qui sont interdit d'apparaître dans une URL:

  • Les caractères de contrôle (caractères 0-1F et 7F), y compris les nouveaux ligne, tabulation et retour chariot.
  • "<>\^`{|}

Tous les autres caractères d'ASCII peuvent légalement figurer dans une URL.

La RFC 3987 étend alors cet ensemble de caractères non réservés avec les plages de caractères unicode suivantes:

  %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

Mais ces choix de bloc semblent bizarres et arbitraires étant donné le dernier Unicode définitions de bloc; c'est probablement parce que les blocs ont été ajoutés dans la décennie écoulée depuis la rédaction de la RFC 3987. La spécification en cours de WhatWG a un liste plus généreuse:

U + 00A0 à U + D7FF, U + E000 à U + FDCF, U + FDF0 à U + FFFD, U + 10000 à U + 1FFFD, U + 20000 à U + 2FFFD, U + 30000 à U + 3FFFD, U + 40000 à U + 4FFFD, U + 50000 à U + 5FFFD, U + 60000 à U + 6FFFD, U + 70000 à U + 7FFFD, U + 80000 à U + 8FFFD, U + 90000 à U + 9FFFD, U + A0000 à U + AFFFD, U + B0000 à U + BFFFD, U + C0000 à U + CFFFD, U + D0000 à U + DFFFD, U + E0000 à U + EFFFD, U + F0000 à U + FFFFD, U + 100000 à U + 10FFFD

Bien sûr, il faut noter que le simple fait de savoir quels caractères peuvent apparaître légalement dans une URL n'est pas suffisant pour reconnaître si une chaîne donnée est une URL légale ou non, puisque certains caractères ne sont légaux que dans certaines parties de l'URL. Par exemple, les caractères réservés [ et ]sont légaux dans le cadre d'un hôte littéral IPv6 dans une URL comme http: // [1080 :: 8: 800: 200C: 417A] / foo mais ne sont légaux dans aucun autre contexte, l'exemple de l'OP http://example.com/file[/].html est illégal.


53
2018-04-16 17:17



Dans votre question complé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 caractères entre crochets ne sont pas valides ici.

Les crochets sont réservés aux URL dans ce format: http://[2001:db8:85a3::8a2e:370:7334]/foo/bar (c'est-à-dire un littéral IPv6 au lieu d'un nom d'hôte)

Cela vaut la peine de lire attentivement la RFC 3986 si vous voulez bien comprendre le problème.


18
2017-12-03 15:46



Tout valide caractères qui peuvent être utilisés dans un URI (un URL est un type de URI) sont définis dans RFC 3986.

Tous les autres caractères peuvent être utilisés dans une URL à condition qu'ils soient "codés en URL" en premier. Cela implique de changer le caractère invalide pour des "codes" spécifiques (généralement sous la forme du symbole de pourcentage (%) 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 non valides.


11
2017-10-10 13:22



Plusieurs plages de caractères Unicode sont valides pour HTML5, même si ce n'est peut-être pas une bonne idée de les utiliser.

Par exemple., href les docs disent http://www.w3.org/TR/html5/links.html#attr-hyperlink-href:

L'attribut href sur les éléments a et area doit avoir une valeur qui est une URL valide potentiellement entourée d'espaces.

Ensuite, la définition de "URL valide" pointe vers http://url.spec.whatwg.org/, qui dit qu'il vise à:

Alignez les RFC 3986 et RFC 3987 avec les implémentations contemporaines et les obsolètes dans le processus.

Ce document définit Points de code URL comme:

ASCII alphanumérique, "!", "$", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/" , ":", ";", "=", "?", "@", "_", "~" et les points de code dans les plages U + 00A0 à U + D7FF, U + E000 à U + FDCF , U + FDF0 à U + FFFD, U + 10000 à U + 1FFFD, U + 20000 à U + 2FFFD, U + 30000 à U + 3FFFD, U + 40000 à U + 4FFFD, U + 50000 à U + 5FFFD, U +60000 à U + 6FFFD, U + 70000 à U + 7FFFD, U + 80000 à U + 8FFFD, U + 90000 à U + 9FFFD, U + A0000 à U + AFFFD, U + B0000 à U + BFFFD, U + C0000 à U + CFFFD, U + D0000 à U + DFFFD, U + E1000 à U + EFFFD, U + F0000 à U + FFFFD, U + 100000 à U + 10FFFD.

Le terme "points de code URL" est alors utilisé dans l'instruction:

Si c n'est pas un point de code URL et non "%", parsez l'erreur.

dans plusieurs parties de l'algorithme d'analyse, y compris le schéma, l'autorité, le chemin relatif, la requête et les états de fragment: donc fondamentalement l'URL entière.

Aussi, le validateur http://validator.w3.org/ passe pour les URL comme "你好", et ne passe pas pour les URL avec des caractères comme des espaces "a b"

Bien sûr, comme l'a mentionné Stephen C, il ne s'agit pas seulement de caractères, mais aussi de contexte: vous devez comprendre l'ensemble de l'algorithme. Mais puisque la classe "points de code URL" est utilisée sur les points clés de l'algorithme, cela donne une bonne idée de ce que vous pouvez utiliser ou non.

Voir également: Caractères Unicode dans les URL


9
2017-08-29 14:19



Pas vraiment une réponse à votre question, mais la validation des URL est vraiment un problème sérieux. Il vaut probablement mieux valider le nom de domaine et laisser la partie requête de l'url être. C'est mon expérience. Vous pourriez aussi avoir recours à la commande ping de l'URL et voir si cela aboutit à une réponse valide, mais cela pourrait être trop pour une tâche aussi simple.

Les expressions régulières pour détecter les URL sont abondantes, google :)


4
2017-10-10 13:19



J'ai besoin de sélectionner le caractère pour diviser les URL en chaîne, j'ai donc décidé de créer une liste de caractères qui ne pouvaient pas être trouvés dans l'URL par moi-même:

>>> allowed = "-_.~!*'();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
>>> from string import printable
>>> ''.join(set(printable).difference(set(allowed)))
'`" <\x0b\n\r\x0c\\\t{^}|>'

Ainsi, les choix possibles sont le saut de ligne, l'onglet, l'espace, l'antislash et "<>{}^|. Je suppose que je vais aller avec l'espace ou la nouvelle ligne. :)


3
2018-02-11 17:57



Je suis arrivé avec quelques expressions régulières pour PHP qui vont convertir les URL en texte en balises d'ancrage. (Tout d'abord, il convertit tous les URL www: urls en http: // puis convertit toutes les urls en https?: // en un 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) );


-1
2017-12-26 18:36



Utilisation urlencode pour autoriser des caractères arbitraires dans votre URL.


-2
2017-10-10 13:19