Est-ce que j'encode les esperluettes dans <a href…>?

157

J'écris du code qui génère automatiquement du HTML et je veux qu'il encode les choses correctement.

Supposons que je génère un lien vers l'URL suivante:

http://www.google.com/search?rls=en&q=stack+overflow

Je suppose que toutes les valeurs d'attribut doivent être encodées en HTML. (Veuillez me corriger si je me trompe.) Cela signifie que si je mets l'URL ci-dessus dans une balise d'ancrage, je devrais encoder l'esperluette comme suit &amp;:

<a href="http://www.google.com/search?rls=en&amp;q=stack+overflow">

Est-ce exact?

JW.
la source
duplication possible de Quels caractères rendent une URL invalide?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
6
@CiroSantilli: il s'agit de chaînes URL réelles; il s'agit de la manière dont ils sont encodés lorsqu'ils apparaissent dans les attributs HTML.
JW.
comme je le vois, l'encodage des esperluettes n'est pas toujours requis en html5, et les réponses sont obsolètes.
qdinar
1
question pour html5: stackoverflow.com/questions/19441750/…
qdinar

Réponses:

175

Oui, ça l'est. Les entités HTML sont analysées à l'intérieur des attributs HTML, et une erreur &créerait une ambiguïté. C'est pourquoi vous devriez toujours écrire &amp;au lieu de simplement& intérieur de tous les attributs HTML.

Cela dit, seuls &et les citations ont besoin être encodés. Si vous avez des caractères spéciaux comme édans votre attribut, vous n'avez pas besoin de les encoder pour satisfaire l'analyseur HTML.

Auparavant, les URL nécessitaient un traitement spécial avec des caractères non ASCII, comme é. Vous deviez encoder ceux à l'aide de pourcent-échappements, et dans ce cas, cela donnerait %C3%A9, car ils étaient définis par la RFC 1738 . Cependant, la RFC 1738 a été remplacée par la RFC 3986 (URI, Uniform Resource Identifiers) et RFC 3987 (IRI, Internationalized Resource Identifiers), sur lesquelles le WhatWG a basé son travail pour définir comment les navigateurs doivent se comporter lorsqu'ils voient une URL non ASCII. caractères depuis HTML5 . Il est donc désormais sûr d'inclure des caractères non ASCII dans les URL, encodés en pourcentage ou non.

zneak
la source
1
J'en étais à peu près sûr, mais j'ai eu un rare moment de doute. Merci d'avoir confirmé.
JW.
1
Vous pouvez également encoder les espaces avec "+" plutôt que% 20 - ce qui rend l'URL plus facile à lire.
NickG
1
+ n'est actuellement pas respecté dans les liens mailto dans le client de messagerie natif iPhone, pour ce que cela vaut.
Ryan Olson
1
éa encore besoin d'encodage: stackoverflow.com/questions/2742852/unicode-characters-in-urls
lulalala
4
J'ajouterais (comme je viens de tomber dans cette erreur) que si vous vous fiez à un moteur de modèle, vous devriez vérifier si cela prend automatiquement en charge l'échappement des entités HTML ou non. Dans mon cas, Twig faisait cela, et j'ai à tort double échappé en écrivant &amp;dans l'attribut de balise au lieu d'utiliser directement &.
Kamafeather
24

Selon les recommandations HTML officielles actuelles, l'esperluette doit être échappée, par exemple, comme &amp;dans des contextes comme celui-ci. Cependant, les navigateurs n'en ont pas besoin et le CR HTML5 propose d'en faire une règle , de sorte que des règles spéciales s'appliquent dans les valeurs d'attribut. Les validateurs HTML5 actuels sont obsolètes à cet égard (voir rapport de bogue avec commentaires).

Il restera possible d'échapper aux esperluettes dans les valeurs d'attributs, mais en dehors de la validation avec les outils actuels, il n'y a aucun besoin pratique de les échapper dans les hrefvaleurs (et il y a un petit risque de faire des erreurs si vous commencez à les échapper).

Jukka K. Korpela
la source
4
XHTML (le vrai XHTML envoyé en tant que application/xhtml+xml) en aura probablement toujours besoin.
zneak
4
Une mise en garde à ce changement, qui fait toujours l'objet de discussions, de débats et d'incompréhensions, est que le &est censé être correct maintenant, tant qu'il est " non ambigu". Une manière évidente de rendre l'esperluette ambiguë est de la suivre d'abord avec des caractères non espace, puis un point-virgule. Ce esperluette est maintenant ambiguë, et va provoquer une erreur d' analyse.
matty
Comme l'a dit Jukka, il y a certainement un risque à encoder toutes les esperluettes, alors considérez la probabilité que l'une de vos URL href contienne un point-virgule. Plutôt improbable, car je ne suis pas sûr d'avoir déjà vu une URL avec un point-virgule. Non pas que cela ne puisse pas être fait. Donc, en pratique, je ne pense pas qu'il soit probable que notre utilisation de &soit ambiguë. Par conséquent, nous continuons à l'utiliser non codé dans les attributs href.
matty
La raison pour laquelle l'évasion est nécessaire est précisément à cause de la possibilité d'une ambiguïté . Ce problème particulier ne concerne peut-être pas l'introduction de vecteurs d'attaque XSS, un mauvais rendu ou un quelconque effet 99,99% du temps, mais ce n'est pas une raison pour ne pas se soucier. S'échapper correctement est difficile et il y a toujours la possibilité de faire des erreurs.
Phil
5

Je poste une nouvelle réponse parce que je trouve que la réponse de zneak ne contient pas assez d'exemples, ne montre pas la gestion du HTML et des URI comme des aspects et des normes différents et manque de petites choses.

Vous avez deux standards concernant les URL dans les liens ( <a href).

La première norme est RFC 1866 (HTML 2.0) où dans "3.2.1. Caractères de données" vous pouvez lire les caractères qui doivent être échappés lorsqu'ils sont utilisés comme valeur pour un attribut HTML. (Les attributs eux-mêmes n'autorisent pas du tout les caractères spéciaux, par exemple, ce <a hr&ef="http://...n'est pas autorisé, ni<a hr&amp;ef="http://... .)

Plus tard, cela est entré dans la norme HTML 4 , les caractères dont vous avez besoin pour échapper sont:

<   to   &lt;
>   to   &gt;
&   to   &amp;
"   to   &quote;
'   to   &apos;

L'autre standard est la RFC 3986 "Generic URI standard", où les URL sont gérées (cela se produit lorsque le navigateur est sur le point de suivre un lien parce que l'utilisateur a cliqué sur l'élément HTML).

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

Il est important d'échapper à ces caractères pour que le client sache s'ils représentent des données ou un délimiteur.

Exemple non échappé:

https://example.com/?user=test&password&te&st&goto=https://google.com

Exemple, URL entièrement légitime

https://example.com/?user=test&password&te%26st&goto=https%3A%2F%2Fgoogle.com

Exemple d'URL entièrement légitime dans la valeur de l'attribut HTML:

https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com

Également des scénarios importants:

  • Javascript comme valeur:

    <img src="..." onclick="window.location.href = &quot;https://example.com/?user=test&amp;password&amp;te%26st&amp;goto=https%3A%2F%2Fgoogle.com&quot;;">...</a>(Oui, ;;c'est exact.)

  • JSON comme valeur:

    <a href="..." data-analytics="{&quot;event&quot;: &quot;click&quot;}">...</a>

  • Objets échappés à l'intérieur des objets échappés, double encodage, URL dans l'URL à l'intérieur du paramètre, etc.

    http://x.com/?passwordUrl=http%3A%2F%2Fy.com%2F%3Fuser%3Dtest&amp;password=&quot;&quot;123

Daniel W.
la source
3

Oui, vous devriez vous convertir &en &amp;.

Cet outil de validation html du W3C est utile pour des questions comme celle-ci. Il vous indiquera les erreurs et les avertissements pour une page particulière.

Randy Greencorn
la source
1
Je ne suis pas sûr que le validateur W3C détecte cela (sans échappement &dans un href) comme une erreur.
ChrisW
6
Actuellement, le validateur W3C accepte sans échappement et comme valide. Cela signifie-t-il que la norme a changé et que l'encodage n'est plus nécessaire? (rendant la plupart des réponses obsolètes ici)? Si tel est le cas, cela s'applique-t-il uniquement à href ou à tout attribut?
matteo