Dois-je vraiment encoder '&' en '& amp;'?

207

J'utilise un &symbole ' ' avec HTML5 et UTF-8 dans mon site <title>. Google montre l'esperluette fine sur ses SERPs, comme le font tous les navigateurs dans leurs titres.

http://validator.w3.org me donne ceci:

& n'a pas commencé de référence de caractère. (& aurait probablement dû être échappé comme &amp;.)

Dois-je vraiment besoin de faire &amp; ?

Je ne m'inquiète pas de la validation de mes pages dans un souci de validation, mais je suis curieux d'entendre les opinions des gens à ce sujet et si c'est important et pourquoi.

Haroldo
la source
63
Les spécifications ne le disent pas. L'affiche fait référence à HTML5 qui ne nécessite pas d'échapper à l'esperluette dans tous les scénarios.
Matthew Wilson
2
Cela devrait être le wiki de la communauté, car vous cherchez des opinions, et ne pas être pointilleux sur la validation implique qu'il n'y a pas de base objective sur laquelle répondre.
Richard JP Le Guen
6
@Richard: vraiment? Même si je ne suis pas d'accord pour dire que "la validation n'a pas d'importance", je vois cela comme une question très objective: "est-ce que cela rompt autre chose que la spécification?"
Joachim Sauer
2
@YiJiang Les navigateurs Web actuels se donnent beaucoup de mal pour comprendre l'utilisateur . Et Google aussi . Cela fait partie de la spécification. Les futurs navigateurs Web pourraient être moins indulgents. C'est donc toujours une bonne idée de vérifier comment Wikipedia le fait et de les copier.
unixman83
2
La spécification HTML dit d'accepter les entrées de merde. Est-ce à dire que votre site est "autorisé" à être de la merde maintenant? Fermez les balises qui doivent être fermées et échappez aux choses! Allez.
doug65536

Réponses:

143

Oui. Tout comme l'erreur l'a dit, en HTML, les attributs sont #PCDATA, ce qui signifie qu'ils sont analysés. Cela signifie que vous pouvez utiliser des entités de caractère dans les attributs. L'utilisation &en elle-même est incorrecte et sinon pour les navigateurs clémentes et le fait qu'il s'agisse de HTML et non de XHTML, casserait l'analyse. Échappez-vous juste comme &amp;et tout irait bien.

HTML5 vous permet de le laisser sans échappatoire, mais uniquement lorsque les données qui suivent ne ressemblent pas à une référence de caractère valide. Cependant, il vaut mieux simplement échapper à toutes les instances de ce symbole que de se soucier de celles qui devraient être et de celles qui n'ont pas besoin d'être.

Gardez ce point à l'esprit; si vous n'échappez pas à & to & amp;, c'est déjà assez mauvais pour les données que vous créez (où le code pourrait très bien être invalide), vous pourriez également ne pas échapper aux délimiteurs de balises, ce qui est un énorme problème pour les données soumises par les utilisateurs, ce qui pourrait très bien conduire à l'injection de HTML et de script, au vol de cookies et à d'autres exploits.

Veuillez simplement échapper votre code. Cela vous évitera beaucoup de problèmes à l'avenir.

Delan Azabani
la source
9
Aucun navigateur ne "mal interprètera" jamais lui-même. Chaque navigateur existant l'affiche sous la forme "&". Considérant qu'il a explicitement demandé une raison pratique de le faire, et qu'il a déclaré qu'il ne se souciait pas de la validation ..
Thomas Bonini
47
Oui. Mais moralement, devrions-nous nous fier à la clémence et à la "gentille" gestion des erreurs des navigateurs? Ou devrions-nous simplement écrire le code correct?
Delan Azabani
8
@Delan: alors que j'essaye de faire valider chaque page que j'écris, je comprends à la lecture de sa question qu'il ne se soucie pas "moralement". Il se soucie juste si cela fonctionne ou non. Ce sont deux philosophies différentes et toutes deux ont leurs avantages et leurs inconvénients, et il n'y en a pas une "correcte". Par exemple, ce site Web ne valide pas, et pourtant c'est un excellent site Web.
Thomas Bonini
3
@Andreas, mais les navigateurs ont suffisamment de bugs dans la façon dont ils interprètent le code correct, selon qu'ils obtiennent les bons résultats lorsque vous leur envoyez un balisage sans signification est hasardeux. Cela peut fonctionner aujourd'hui avec cet exemple, puis échouer avec l'exemple suivant (par exemple, si l'exemple suivant a un point-virgule quelque part après le &)
Jon Hanna
11
Tout le monde semble parler de HTML5, mais la question d'origine indique que HTML5 est utilisé. HTML5 autorise explicitement un échappé & dans cette situation, à moins que ce qui suit & ne se développe normalement à une entité (par exemple & copy = 2 est problématique mais & x = 2 est bien).
Matthew Wilson
55

Hormis la validation, il n'en demeure pas moins que le codage de certains caractères est important pour un document HTML afin qu'il puisse s'afficher correctement et en toute sécurité sous forme de page Web.

Encodage en &tant que&amp; dans toutes les circonstances, pour moi, est une règle plus facile à vivre, réduisant la probabilité d'erreurs et d'échecs.

Comparez ce qui suit: qu'est-ce qui est plus facile? ce qui est plus facile à enculer ?

Méthodologie 1

  1. Écrivez du contenu comprenant des esperluettes.
  2. Encodez-les tous.

Méthodologie 2

(avec un grain de sel, s'il vous plaît;))

  1. Écrivez du contenu qui comprend une esperluette.
  2. Au cas par cas, examinez chaque esperluette. Déterminez si:
    • Il est isolé, et en tant que tel sans équivoque une esperluette. par exemple.volt & amp
       > Dans ce cas, ne vous embêtez pas à l'encoder.
    • Elle n'est pas isolée, mais vous pensez qu'elle est néanmoins sans ambiguïté, car l'entité résultante n'existe pas et n'existera jamais car la liste d'entités ne pourra jamais évoluer. par exempleamp&volt
       > Dans ce cas, ne vous embêtez pas à l'encoder.
    • Il n'est pas isolé et ambigu. par exemple. volt&amp
       > Encodez-le.

??

Richard JP Le Guen
la source
3
Le deuxième cas amp&volt est ambigu: est-ce &voltmaintenant une référence d'entité ou non?
Gumbo
6
@Gumbo L'esperluette dans amp&voltn'est pas une esperluette ambiguë (selon la définition de la spécification HTML). Voir mathiasbynens.be/notes/ambiguous-ampersands et mothereff.in/ampersands#amp%26volt .
Mathias Bynens
@MathiasBynens À présent (2019), la définition d'une esperluette ambiguë semble avoir légèrement changé par rapport à la définition que vous avez citée en 2011 dans mathiasbynens.be/notes/ambiguous-ampersands .
Jacob C. dit Réintégrer Monica
21

Les règles HTML5 sont différentes de HTML4. Ce n'est pas nécessaire en HTML5 - à moins que l'esperluette ne semble commencer un nom de paramètre. "& copy = 2" est toujours un problème, par exemple, car & copy; est le symbole du droit d'auteur.

Cependant, il me semble qu'il est plus difficile de décider de coder ou de ne pas coder en fonction du texte suivant. Ainsi, le chemin le plus simple est probablement de coder tout le temps.

Matthew Wilson
la source
2
C'est comme citer des valeurs d'attribut - ce n'est pas obligatoire, mais vous ne pouvez pas vous tromper si vous le faites tout le temps.
Paul D. Waite
3
&copy=2n'est pas un problème aussi important que vous ne le pensez. Dans les valeurs d'attribut (par exemple l' hrefattribut), le &copyne sera pas considéré comme une référence de caractère pour ©. En dehors d'une valeur d'attribut, ce serait le cas.
Mathias Bynens
Étant donné qu'une esperluette est normalement précédée et suivie d'un espace dans le texte anglais, il n'est pas difficile de se rappeler ou de penser à la règle que je respecte: si l'esperluette ne touche pas un autre caractère visible, ce qui est presque toujours le cas, elle n'a pas besoin codage. Sinon, encodez simplement pour plus de simplicité.
Carl Smith
Pourriez-vous ajouter une référence aux règles HTML5?
Ferrybig
17

Je pense que cela est devenu plus une question de "pourquoi suivre les spécifications lorsque le navigateur ne s'en soucie pas." Voici ma réponse généralisée:

Les normes ne sont pas une chose "présente". Ils sont une chose "future". Si nous, en tant que développeurs, suivons les normes Web, alors les fournisseurs de navigateurs sont plus susceptibles de mettre correctement en œuvre ces normes, et nous nous rapprochons d'un Web complètement interopérable, où les hacks CSS, la détection des fonctionnalités et la détection des navigateurs ne sont pas nécessaires. Où nous n'avons pas à comprendre pourquoi nos mises en page se brisent dans un navigateur particulier, ou comment contourner cela.

Plus précisément, si HTML5 ne nécessite pas l'utilisation de & amp; dans votre situation spécifique et que vous utilisez un doctype HTML5 (et que vous vous attendez également à ce que vos utilisateurs utilisent des navigateurs compatibles HTML5), il n'y a aucune raison de le faire.

Ryan Kinal
la source
1
Cela étant dit, d'une manière générale, vous devez vous rappeler que la plupart des méthodes "standard" sont encore en mode brouillon et pourraient changer à l'avenir.
refaelio
6

Eh bien, si cela vient de la saisie de l'utilisateur, alors absolument oui, pour des raisons évidentes. Pensez si ce site Web ne l'a pas fait: le titre de cette question apparaîtrait, car ai-je vraiment besoin de coder '&' en '&'?

Si c'est juste quelque chose comme ça à echo '<title>Dolce & Gabbana</title>';proprement parler, vous n'avez pas à le faire. Ce serait mieux, mais si vous ne le faites pas, aucun utilisateur ne remarquera la différence.

Thomas Bonini
la source
5

Pourriez-vous nous montrer ce que vous êtes titleréellement? Quand je soumets

<!DOCTYPE html>
<html>
<title>Dolce & Gabbana</title>
<body>
<p>am i allowed loose & mpersands?</p>
</body>
</html>

à http://validator.w3.org/ - lui demandant explicitement d'utiliser le mode expérimental HTML 5 - il ne se plaint pas du &s ...

AakashM
la source
1
Oui, HTML5 a un analyseur différent des analyseurs HTML et XHTML précédents et permet des esperluettes sans échappatoire dans certaines situations.
kevinji
En ce qui concerne ces exemples, ce n'est pas nouveau en HTML5. Les deux <title>Dolce & Gabbana</title>et <p>Dolce & Gabbana</p>sont valides HTML 2.0.
Mathias Bynens
4

En HTML, a &marque le début d'une référence, soit d'une référence de caractère , soit d'une référence d' entité . À partir de ce moment, l'analyseur attend soit une #dénotation d'une référence de caractère, soit un nom d'entité dénotant une référence d'entité, tous deux suivis d'un ;. Voilà le comportement normal.

Mais si le nom de référence ou tout simplement l'ouverture de référence &est suivi d'un espace blanc ou d' autres délimiteurs comme ", ', <, >, &, la fin ;et même une référence pour représenter une plaine &peut être omise:

<p title="&amp;">foo &amp; bar</p>
<p title="&amp">foo &amp bar</p>
<p title="&">foo & bar</p>

Ce n'est que dans ces cas que la fin ;ou même la référence elle-même peut être omise (au moins en HTML 4). Je pense que HTML 5 nécessite la fin; .

Mais la spécification recommande de toujours utiliser une référence comme la référence de caractère &#38;ou la référence d'entité &amp;pour éviter toute confusion:

Les auteurs doivent utiliser " &amp;" (ASCII décimal 38) au lieu de " &" pour éviter toute confusion avec le début d'une référence de caractère (délimiteur ouvert de référence d'entité). Les auteurs doivent également utiliser " &amp;" dans les valeurs d'attribut car les références de caractères sont autorisées dans les valeurs d'attribut CDATA.

Gombo
la source
1
C'est la spécification HTML 4 à laquelle vous liez; d'après ma lecture de la (version préliminaire) spécification HTML 5, seules les esperluettes ambiguës sont interdites. Une esperluette suivie d'un espace, par exemple, n'est pas ambiguë, et donc (encore une fois par ma lecture) devrait être autorisée - voir ma réponse pour le balisage que le validateur HTML 5 accepte.
AakashM
1
@AakashM: Je ne suis pas sûr, ça sonnait comme ça.
Gumbo
3

Si l'utilisateur vous le transmet ou qu'il se retrouve dans une URL, vous devez y échapper.

S'il apparaît en texte statique sur une page? Tous les navigateurs obtiendront celui-ci dans les deux cas, vous ne vous en souciez pas beaucoup, car cela fonctionnera.

Dean J
la source
3

Mise à jour (mars 2020): le validateur W3C ne se plaint plus de l'échappement des URL.

Je vérifiais pourquoi le besoin de l'URL de l'image s'échappait, donc je l'ai essayé dans https://validator.w3.org . L'explication est plutôt sympa. Il souligne que même les URL doivent être échappées. [PS: Je suppose que cela ne s'échappera pas quand il sera consommé depuis le besoin de l'URL &. Quelqu'un peut-il clarifier?]

<img alt="" src="foo?bar=qut&qux=fop" />

Une référence d'entité a été trouvée dans le document, mais aucune référence de ce nom n'est définie. Souvent, cela est dû à une faute d'orthographe sur le nom de référence, des esperluettes non codées, ou à la suppression du point-virgule (;). La cause la plus courante de cette erreur est les esperluettes non codées dans les URL, comme décrit par le WDG dans «Esperluettes dans les URL». Les références d'entité commencent par une esperluette (&) et se terminent par un point-virgule (;). Si vous souhaitez utiliser une esperluette littérale dans votre document, vous devez l'encoder en "&" (même à l'intérieur des URL!). Veillez à terminer les références d'entité par un point-virgule ou votre référence d'entité peut être interprétée en relation avec le texte suivant. Gardez également à l'esprit que les références d'entité nommées sont sensibles à la casse; & Aelig; et æ sont des caractères différents.

Nishant
la source
1
Lisez la réponse la mieux notée. Les attributs sont #PCDATA et donc analysés. Les entités y sont gérées. Dans votre exemple, le &démarre une référence d'entité. Après lecture &qux, l'analyseur ne trouve pas de point-virgule final ( ;), mais rencontre un signe égal ( =), qui ne peut pas faire partie du nom de l'entité. Cela devrait être une erreur d'analyse, si l'analyseur a essayé d'être vraiment strict (selon HTML 4). Dans HTML 5, l'analyse des entités est globalement plus détendue.
Palec
1
Je soupçonne qu'en général, il est préférable d'utiliser ;comme séparateur dans les chaînes de requête (lorsque vous contrôlez le lien) pour cette raison.
Demi
2

Oui, si possible, essayez de diffuser un code valide.

La plupart des navigateurs corrigent silencieusement cette erreur, mais il y a un problème avec la gestion des erreurs dans les navigateurs. Il n'y a pas de norme pour gérer le code incorrect, il appartient donc à chaque fournisseur de navigateur d'essayer de savoir quoi faire avec chaque erreur, et les résultats peuvent varier.

Voici quelques exemples où les navigateurs sont susceptibles de réagir différemment: si vous placez des éléments dans un tableau mais en dehors des cellules du tableau, ou si vous imbriquez des liens les uns dans les autres.

Pour votre exemple spécifique, il est peu probable que cela cause des problèmes, mais la correction d'erreurs dans le navigateur peut par exemple entraîner le passage du mode conforme aux normes au mode bizarreries, ce qui pourrait entraîner une panne complète de votre mise en page.

Donc, vous devez corriger des erreurs comme celle-ci dans le code, sinon pour autre chose, afin de garder la liste d'erreurs dans le validateur courte, afin que vous puissiez repérer des problèmes plus graves.

Guffa
la source
2

Il y a quelques années, nous avons appris que l'une de nos applications Web ne s'affichait pas correctement dans Firefox. Il s'est avéré que la page contenait une balise qui ressemblait à

<div style="..." ... style="...">

Face à un attribut de style répété, IE combine les deux styles, tandis que Firefox n'en utilise qu'un, d'où le comportement différent. J'ai changé le tag en

<div style="...; ..." ...>

et bien sûr, cela a résolu le problème! La morale de l'histoire est que les navigateurs ont une gestion plus cohérente du HTML valide que du HTML invalide. Alors, corrigez déjà votre fichu balisage! (Ou utilisez HTML Tidy pour le réparer.)

dan04
la source
1

si &est utilisé en html, vous devez y échapper

Si &est utilisé dans des chaînes javascript, par exemple an alert('This & that');ou document.href, vous n'avez pas besoin de l'utiliser.

Si vous utilisez document.write, vous devez l'utiliser par exemple document.write(<p>this &amp; that</p>)

Alex
la source
document.writedevrait être évité. Voir la boîte d'avertissement dans w3.org/html/wg/drafts/html/master/dom.html#document.write%28%29
Oriol
Bon point document.write(). Mais le point essentiel qu'Alex fait au sujet de l'écriture dans le document à partir de supports de script, imo. +1
Patrick M
1

Cela dépend de la probabilité qu'un point-virgule finisse près de votre &, ce qui l'aidera à afficher quelque chose de très différent.

Par exemple, lorsque vous traitez des entrées d'utilisateurs (par exemple, si vous incluez le sujet fourni par l'utilisateur d'un message de forum dans vos balises de titre), vous ne savez jamais où ils pourraient placer des points-virgules aléatoires, et cela pourrait afficher au hasard des entités étranges. Alors, évadez-vous toujours dans cette situation.

Pour votre propre html statique, bien sûr, vous pouvez l'ignorer, mais il est si trivial d'inclure un échappement approprié, qu'il n'y a aucune bonne raison de l'éviter.

Douglas
la source
0

Si vous parlez vraiment du texte statique

<title>Foo & Bar</title>

stocké dans un fichier sur le disque dur et servi directement par un serveur, alors oui: il n'a probablement pas besoin d'être échappé.

Cependant, étant donné qu'il est très peu de contenu HTML de nos jours qui est complètement statique, j'ajouterai la clause de non-responsabilité suivante qui suppose que le contenu HTML est généré à partir d'une autre source (contenu de la base de données, entrée utilisateur, résultat de l'appel de service Web, résultat de l'API hérité). ..):

Si vous n'échappez pas simple &, alors les chances sont que vous aussi ne pas échapper à un &amp;ou &nbsp;ou <b>ou <script src="http://attacker.com/evil.js">ou tout autre texte non valide. Cela signifie que vous affichez au mieux votre contenu de manière incorrecte et que vous êtes plus susceptible d'être suspecté d' attaques XSS .

En d'autres termes: lorsque vous vérifiez déjà et échappez aux autres cas plus problématiques, il n'y a presque aucune raison de laisser le non-totalement-cassé-mais-encore-quelque peu louche-autonome et sans échappatoire.

Joachim Sauer
la source
2
Je n'ai pas downvote mais, si je devais deviner, je dirais que vous avez été downvote parce que votre réponse (bien qu'intelligente) est un peu en décalage avec la question. Il ne demande pas à échapper aux entrées des utilisateurs. Il a le contrôle sur les personnages et demande essentiellement "S'il fait ce que je veux, est-il vraiment important de suivre les spécifications linguistiques à la lettre?" C'est à dire, il sait qu'il y a un & parce qu'il l'a mis.
Matt
@Matt: Je vois, et ce serait raisonnable. Je supposais simplement que personne n'écrit plus de pages HTML entièrement statiques et que presque tout le contenu est au moins quelque peu dynamique (généralement basé sur du contenu de base de données). Peut-être que cette hypothèse aurait dû être explicite.
Joachim Sauer
-1

Je ne sais pas si cela est utile à quiconque ... Je me battais contre cela pendant un certain temps ... voici une expression régulière glorieuse que vous pouvez utiliser pour corriger tous vos liens, javascript, contenu. J'ai dû gérer une tonne de contenu hérité que personne ne voulait corriger.

Ajoutez ceci à votre remplacement de rendu dans votre page maître ou votre contrôle:

S'il vous plaît, ne me faites pas flamber pour avoir mis cela au mauvais endroit:

// remove the & from href="blaw?a=b&b=c" and replace with &amp; 
//in urls - this corrects any unencoded & not just those in URL's
// this match will also ignore any matches it finds within <script> blocks AND
// it will also ignore the matches where the link includes a javascript command like
// <a href="javascript:alert{'& & &'}">blaw</a>
html = Regex.Replace(html, "&(?!(?<=(?<outerquote>[\"'])javascript:(?>(?!\\k<outerquote>|[>]).)*)\\k<outerquote>?)(?!(?:[a-zA-Z][a-zA-Z0-9]*|#\\d+);)(?!(?>(?:(?!<script|\\/script>).)*)\\/script>)", "&amp;", RegexOptions.Singleline | RegexOptions.IgnoreCase);
Richard Dufour
la source
-1

Le lien a un assez bon exemple de quand et pourquoi vous devrez peut-être vous échapper &pour&amp;

https://jsfiddle.net/vh2h7usk/1/

Fait intéressant, j'ai dû échapper au personnage afin de le représenter correctement dans ma réponse ici. Si je devais utiliser l' option d' échantillon de code intégré (à partir du panneau de réponses), je peux simplement taper &amp;et il apparaît comme il se doit. Mais si je devais utiliser manuellement l' <code></code>élément, je dois m'échapper pour le représenter correctement :)

mathin
la source