Quels caractères rendent une URL invalide?
quels caractères invalident une URL?
sont-elles des URL valides?
-
example.com/file[/].html
-
http://example.com/file[/].html
10 réponses
en URI général tel que défini 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ù ces caractères peuvent apparaître dans L'URI.
tout autre caractère doit être encodé avec le pourcentage d'encodage ( %
hh
). Chaque partie de L'URI a d'autres restrictions sur les caractères qui doivent être représentés par un mot encodé en pourcentage.
pour apporter quelques précisions et répondre directement à la question ci-dessus, il existe plusieurs classes de caractères qui causent des problèmes pour les URLs et URIs.
il y a des caractères qui sont rejetés et qui 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 causer des problèmes dans certains cas, mais qui sont marqués comme" imprudent "ou"dangereux". Les raisons pour lesquelles les caractères sont restreints sont clairement énoncées dans RFC-1738 (URLs) et RFC-2396 (URIs). Remarque le plus récent la RFC 3986 (mise à jour de la RFC 1738) définit la construction de ce que les caractères sont autorisés dans un contexte donné, mais les aînés spec offre un moyen plus simple et plus description générale dont les caractères ne sont pas autorisés avec les règles suivantes.
Exclus US-ASCII des Caractères interdits dans la syntaxe d'URI:
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space = <US-ASCII coded character 20 hexadecimal>
delims = "<" | ">" | "#" | "%" | <">
Liste des imprudent caractères sont autorisés, mais peut causer des problèmes:
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
caractères réservés dans un composant de requête et / ou ayant 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 qui sont autorisés dans une URI, mais qui ne peuvent pas l'être dans un composant particulier de la syntaxe URI Générique. les caractères de l'ensemble" réservé " ne sont pas Tous réservés. contextes de . Le nom d'hôte, par exemple, peut contenir un nom d'utilisateur optionnel de sorte qu'il pourrait être quelque chose comme ftp://user@hostname/
où le caractère " @ " a une signification particulière.
voici un exemple d'URL qui a des caractères invalides et imprécis (par ex. '$', '[', ']') et doit être correctement codé:
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 URIs/URLs dépendent du langage de programmation. Par exemple, le caractère ' | ' (0x7C) bien que seulement marqué comme "unwise" dans L'URI spec lancera 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ée et doit être encodée à la place de http://api.google.com/q?exp=a%7Cb
si vous utilisez Java avec une instance D'objet URI.
la plupart des réponses existantes ici sont impraticables parce qu'ils ignorent totalement l'usage réel des adresses comme:
Ok, donc selon RFC 3986 , ces adresses ne sont pas URIs (et par conséquent pas D'URLs, puisque les URLs sont un type D'URIs ). Si nous nous considérons redevables à la terminologie des normes existantes de L'IETF, alors nous devrions les appeler correctement IRIs (identificateurs de ressources internationalisés), tel que défini dans RFC 3987 , qui ne sont pas techniquement URIs mais peuvent être convertis en URIs simplement par le pourcentage-encodant tous les caractères non-ASCII dans L'IRI. Les gens normaux, cependant, n'ont jamais entendu parler D'IRIs et appellent simplement ces URIs ou URLs (et en effet il y a un WHATWG effort en cours pour créer une nouvelle, plus large spécification D'URL qui classe simplement tous les "URIs" et "IRIs" comme "URLs" pour aligner avec l'usage moderne de ces termes dans le monde réel).
supposons que nous voulons adopter immédiatement cette signification D'URL (ce qui met en contradiction avec les spécifications IETF, mais nous aligne avec l'usage quotidien). 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 d'un URI défini dans la RFC 3986 -
!$&'()*+,;=
, qui ne font pas partie de la syntaxe générique de la RFC, mais sont réservés pour une utilisation comme composants syntaxiques de schémas URI particuliers. Par exemple, les points-virgules et les virgules sont utilisées dans le cadre de la syntaxe de URIs de données , et&
et=
sont utilisées dans le cadre du format ubiquitaire?foo=bar&qux=baz
dans les chaînes de requête (qui n'est pas spécifié par RFC 3986).
N'importe lequel des caractères réservés ci-dessus peut être utilisé légalement dans un URI sans encodage, soit pour servir leur but syntaxique ou tout simplement comme des caractères littéraux dans les données dans certains endroits où une telle utilisation ne pourrait pas être mal interprété comme le personnage servant son but syntaxique. (Par exemple, bien que /
ait une signification syntaxique dans une URL, vous pouvez l'utiliser dans une chaîne de requête, parce que n'a pas de signification dans une chaîne de requête.)
RFC 3986 spécifie également quelques caractères sans réserve , qui peuvent toujours être utilisés simplement pour représenter des données sans aucun encodage:
-
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
enfin, le caractère %
lui-même est autorisé pour les pourcentages d'encodage.
qui ne laisse apparaître que les caractères ASCII suivants qui sont interdit dans une URL:
- les caractères de contrôle (caractères 0-1F et 7F), y compris la nouvelle ligne, l'onglet et le retour de chariot.
-
"<>\^`{|}
tout autre caractère D'ASCII peut légalement figurer dans une URL.
puis RFC 3987 étend cet ensemble de caractères sans réserve avec les gammes 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 blocs semblent bizarres et arbitraires étant donné le dernier Unicode définitions de blocs ; c'est probablement parce que les blocs ont a été ajouté dans la décennie depuis la RFC 3987 a été écrit. La spécification en cours de WhatWG a une 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 to U+EFFFD, U+F0000 to U+FFFFD, U+100000 to U+10FFFD
bien sûr, il faut noter que le simple fait de savoir quels caractères peuvent légalement apparaître dans une URL n'est pas suffisant pour reconnaître si une chaîne de caractères 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 en tant que partie d'un hôte littéral IPv6 dans une URL comme http://[1080::8:800:200C: 417A] / foo mais ne sont pas légales dans un autre contexte, de sorte que l'exemple de L'OP http://example.com/file[/].html
est illégal.
dans votre question supplémentaire, vous avez demandé si www.example.com/file[/].html
était 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, alors la réponse est non car les caractères entre crochets ne sont pas valides.
les caractères entre crochets sont réservés pour les URLs dans ce format: http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(C'est-à-dire un IPv6 littéral au lieu d'un nom d'hôte)
Il est intéressant de lire la RFC 3986 attentivement, si vous voulez comprendre le problème entièrement.
tous les valide les 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" encodés URL " en premier. Il s'agit de changer le caractère invalide pour des "codes" spécifiques (habituellement sous la forme du symbole de pourcentage (%) 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.
plusieurs des plages de caractères Unicode sont valides HTML5 , bien qu'il puisse ne pas être une bonne idée de les utiliser.
par exemple, href
docs say 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.
puis le définition de "URL valide" pointant vers http://url.spec.whatwg.org / , qui dit qu'il vise à:
alignent RFC 3986 et RFC 3987 avec les implémentations contemporaines et les obsolètes dans le processus.
ce document définit URL code points comme:
ASCII alphanumérique,"!", "$", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", ":", ";", "=", "?", "@", "_", "~", et les points de code dans les gammes 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 to U+8FFFD, U+90000 to U+9FFFD, U+A0000 to U+AFFFD, U+B0000 to U+BFFFD, U+C0000 to U+CFFFD, U+D0000 to U+DFFFD, U+E1000 to U+EFFFD, U+F0000 to U+FFFFD, U+100000 to U+10FFFD.
le terme "points de code URL" est alors utilisé dans la déclaration:
si c n'est pas un point de code URL et non"%", erreur d'analyse.
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 essentiellement L'URL entière.
aussi, le validateur http://validator.w3.org / passe pour des URLs comme "你好"
, et ne passe pas pour les URLs avec des caractères comme les 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'algorithme entier. 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 aussi: caractères Unicode dans les URLs
je dois sélectionner un caractère pour diviser les urls en chaîne, donc j'ai décidé de créer la liste des 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 la nouvelle ligne, tab, espace, antislash et "<>{}^|
. Je crois que je vais aller avec l'espace ou saut de ligne. :)
Pas vraiment de réponse à votre question, mais de la validation d'url est vraiment une grave p.j'.t.un Vous êtes probablement juste mieux de valider le nom de domaine et laisser la partie requête de l'url être. C'est mon expérience. Vous pouvez aussi utiliser l'url pour voir si elle donne 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 it :)
j'ai trouvé quelques expressions régulières pour PHP qui convertiront les urls dans le texte en balises d'ancrage. (D'abord il convertit tout www. url: http:// convertit ensuite toutes les url en https?:// pour un href=... liens html
$string = preg_replace('/(https?:\/\/)([!#$&-;=?\-\[\]_a-z~%]+)/sim', '<a href=""></a>',
preg_replace('/(\s)((www\.)([!#$&-;=?\-\[\]_a-z~%]+))/sim', 'http://', $string)
);