Outils de développement · Encodeur et décodeur d'URL
WHATWG URL Standard vs RFC 3986 : pourquoi les navigateurs et les bibliothèques ne sont pas d'accord
· Contexte
encodage d'URL normes outils de développement
Il existe deux définitions vivantes d'une URL, et elles sont volontairement en désaccord. Cet article explique pourquoi le WHATWG a écrit sa propre norme, où les deux diffèrent par l'encodage et l'analyse, et laquelle suit votre code.
L'URL qu'une bibliothèque stricte rejette et que le navigateur charge avec plaisir : une chaîne, deux verdicts
Une chaîne avec une barre oblique inverse en JavaScript peut être interprétée facilement par votre navigateur comme faisant partie du chemin de l'URL. La même chaîne atteint le backend d'une bibliothèque Python et celle-ci refuse de l'analyser car les barres obliques inverses ne sont pas autorisées. Une URL, deux résultats différents. Ni l’un ni l’autre n’a tort : ils suivent des normes différentes. La norme WHATWG décrit ce que font réellement les navigateurs avec les URL du monde réel, y compris la manière dont ils gèrent les entrées mal formées. La RFC 3986 définit une grammaire formelle à laquelle les URL devraient idéalement se conformer. De nombreuses bibliothèques back-end construites sur RFC 3986 appliquent strictement cette grammaire et rejettent tout ce qui se trouve en dehors d'elle.
Cette divergence est importante lorsque vous déplacez des données entre des environnements. Une URL acceptée par les navigateurs peut échouer à la validation dans un outil backend. Comprendre quelle norme votre code implémente évite les problèmes fantômes de débogage : les URL fonctionnent correctement à un endroit mais échouent mystérieusement ailleurs sans raison apparente.
Pourquoi le WHATWG a recommencé : décrivant ce que les navigateurs font réellement avec des entrées mal formées plutôt que ce qui est valide
Le groupe de travail WHATWG s'est formé en 2004 pour standardiser la façon dont les navigateurs gèrent réellement les URL dans la pratique, plutôt que de définir des règles formelles plus strictes que les navigateurs ne suivraient pas. La RFC 2396 décrit une spécification de grammaire formelle, mais dans la pratique, les navigateurs ne la suivent jamais exactement correctement. Les navigateurs du monde réel ont développé des règles pratiques pour tolérer les espaces, gérer les caractères d'échappement et récupérer des entrées mal formées que la RFC n'avait pas anticipées ou attendues.
RFC 3986 est arrivé dans 2005 avec une grammaire formelle pour des URL bien formées et des exigences strictes. Les navigateurs implémentent WHATWG ; les bibliothèques backend implémentent souvent RFC 3986.
Ensembles d'encodage par rapport aux caractères réservés – comment les listes par composant de la norme d'URL se rapportent aux catégories de la RFC 3986
RFC 3986 divise les caractères en trois catégories : réservés, non réservés et tout ce qui doit être codé. Les caractères réservés comme les deux points, la barre oblique, le point d'interrogation et le hachage ont une signification structurelle dans les URL. Les caractères non réservés sont les lettres, les chiffres, le trait d'union, le trait de soulignement, le point et le tilde ; ceux-ci sont toujours sûrs. Tout le reste est codé en pourcentage sous forme d'octets. Le standard fournit une règle claire : sachez à quelle catégorie appartient votre personnage.
La norme URL WHATWG adopte une approche basée sur les composants. Il spécifie différentes règles de codage pour le schéma, l'autorité, le chemin, la requête et le fragment séparément au lieu d'utiliser des catégories globales. Une esperluette peut être codée dans un chemin mais laissée seule dans une chaîne de requête. Un espace est toujours codé, mais la représentation exacte varie selon le contexte. Cette conception par composant correspond bien mieux au comportement du navigateur, mais nécessite de savoir quelle partie de l'URL vous encodez.
Tolérance d'erreur : espaces, barres obliques inverses et tabulations – les entrées d'un standard sont rejetées et l'autre répare
Les espaces doivent devenir %20 selon les deux normes, mais les navigateurs convertissent silencieusement les espaces littéraux. Les barres obliques inverses sont interdites par les deux standards, mais certains navigateurs les traitent comme des séparateurs de chemin. Les tabulations, les nouvelles lignes et les caractères de contrôle sont interdits. WHATWG spécifie un comportement indulgent de l'analyseur : convertissez-les ou ignorez-les.
Les caractères non-ASCII comme é ou 中 doivent être codés en pourcentage à l'aide du codage UTF-8. La RFC 3986 ne spécifie pas réellement l'étape de codage des caractères elle-même ; il suppose que les octets existent mais ne dit pas comment les obtenir à partir du texte. La norme WHATWG exige explicitement UTF-8 : transformez d'abord la chaîne en UTF-8 octets, puis encodez-les en pourcentage. Les deux normes aboutissent au même résultat de codage, mais elles partent d’hypothèses sous-jacentes différentes et ne sont pas explicites sur les mêmes choses.
Exemple concret : analyse d'une URL avec une barre oblique inverse et un espace dans les deux modèles - les sorties comparées
Prenons l'exemple de chaîne "https://example.com/café\ search". Un navigateur rencontre la barre oblique inverse et la considère comme un caractère de chemin ; il voit l'espace et l'encode en %20, produisant quelque chose comme https://example.com/café%5C%20search.. Un analyseur RFC 3986 rejette immédiatement l'URL entière car les barres obliques inverses sont interdites et les espaces sont interdits. Le navigateur continue l'analyse ; l'analyseur strict s'arrête complètement. Essayez un autre exemple : "https://user@example.com:80/path?q=a&b=c". Les deux normes identifient clairement les informations utilisateur, l'hôte, le port, le chemin et la requête. Ils sont entièrement d'accord sur cette URL structurée. Le désaccord ne se produit que sur des entrées inhabituelles ou mal formées.
Ouvrez l'encodeur et le décodeur d'URL et comparez le mode RFC 3986 avec le comportement du navigateur. Collez une chaîne avec des espaces, des barres obliques inverses ou d'autres cas extrêmes. L'outil vous montre exactement comment chaque norme transforme différemment la même entrée. Vous voyez immédiatement lequel est le plus strict et ce que chacun fait.
Lequel votre environnement utilise – les navigateurs et Node suivent la norme URL ; de nombreuses bibliothèques de serveurs suivent la RFC, décrite de manière générale
Dans les navigateurs, JavaScript utilise par défaut la norme d'URL WHATWG. L'API URL l'implémente exactement. Node.js utilise également WHATWG. Les bibliothèques Python ont tendance à implémenter la RFC 3986 ; urllib le suit de près. Les bibliothèques Java varient ; java.net.URL tend vers RFC 3986. La caisse d'URL de Rust suit WHATWG. Le net/url de Go est influencé par WHATWG. Il s’agit d’un modèle général et non d’une règle absolue.
Lorsque vous créez des URL par programme et qu'elles se déplacent entre le navigateur et le backend, choisissez une norme et respectez-la. Utilisez l'API URL du navigateur pour WHATWG. Si votre bibliothèque backend est plus stricte, ce n'est pas une contradiction mais un choix de conception.
Ce que cela ne couvre pas : analyse du nom d'hôte, littéraux IPv6 et traitement IDNA
L'analyse du nom d'hôte implique des règles IDNA, punycode et registraire qui vont au-delà de l'analyse des URL elle-même. Les adresses IPv6, les schémas spéciaux comme mailto: ou data: et les composants vides sont des sujets distincts complètement distincts du codage en pourcentage. Les limites de longueur de domaine et la validité du nom d'hôte varient selon le registraire et ne sont pas pertinentes pour cette discussion. Également exclus : les références relatives et les règles d'analyse spécifiques au schéma. Cet article se concentre uniquement sur les différences d’encodage et d’analyse.
Cette discussion se concentre sur les différences d'encodage et d'analyse qui distinguent ces normes. L'exclusion des règles de nom d'hôte, des règles DNS et du comportement spécifique au schéma évite toute confusion sur les règles de codage en pourcentage.
À retenir : la même URL est valide dans un monde et une erreur dans un autre - comment l'encodeur et le décodeur d'URL vous donnent l'encodage RFC 3986 simple afin que vous puissiez voir ce que le navigateur a normalisé
La même chaîne d'URL peut être valide selon une norme et invalide selon une autre. Les deux ont raison dans le cadre de leurs propres objectifs de conception. Lorsque vous encodez des composants d'URL par programme, utilisez l'outil adapté à votre environnement. WHATWG décrit ce que font réellement les navigateurs ; La RFC 3986 définit la grammaire formelle. L'encodeur et le décodeur d'URL affichent les règles RFC 3986 ainsi que le comportement du navigateur afin que vous puissiez voir les différences exactes et choisir celle qui correspond à votre situation.
Les problèmes apparaissent le plus souvent lorsque les URL franchissent les frontières du navigateur vers le backend. Comprendre cette différence signifie gérer ce passage intentionnellement plutôt qu’accidentellement ou par erreur.