</script>
doit être rompu car sinon il mettrait fin au <script></script>
bloc de fermeture trop tôt. Vraiment, il devrait être divisé entre le <
et le /
, car un bloc de script est censé (selon SGML) se terminer par une séquence ETAGO (end-tag open) (c'est-à-dire </
) :
Bien que les éléments STYLE et SCRIPT utilisent CDATA pour leur modèle de données, pour ces éléments, CDATA doit être géré différemment par les agents utilisateurs. Le balisage et les entités doivent être traités comme du texte brut et transmis à l'application tels quels. La première occurrence de la séquence de caractères " </
" (délimiteur ouvert de balise de fin) est traitée comme terminant la fin du contenu de l'élément. Dans les documents valides, ce serait la balise de fin de l'élément.
Cependant, dans la pratique, les navigateurs ne terminent l'analyse d'un bloc de script CDATA que sur une </script>
balise de fermeture réelle .
En XHTML, il n'y a pas une telle manipulation spéciale pour les blocs de script, donc tout caractère <
(ou &
) à l'intérieur doit être &escaped;
comme dans n'importe quel autre élément. Cependant, les navigateurs qui analysent le XHTML en HTML à l'ancienne seront confus. Il existe des solutions de contournement impliquant des blocs CDATA, mais il est plus simple d'éviter simplement d'utiliser ces caractères sans échapper. Une meilleure façon d'écrire un élément de script à partir d'un script qui fonctionne sur l'un ou l'autre type d'analyseur serait:
<script type="text/javascript">
document.write('\x3Cscript type="text/javascript" src="foo.js">\x3C/script>');
</script>
\/
est une séquence d'échappement valide pour/
, alors pourquoi ne pas simplement l'utiliser à la place de ces échappements littéraux de chaîne pour<
? Par exempledocument.write('<script src=foo.js><\/script>');
. En outre, ce</script>
n'est pas la seule séquence de caractères qui peut fermer un<script>
élément. Plus d'infos ici: mathiasbynens.be/notes/etago<\/script>
c'est bien dans ce cas, mais cela ne fonctionnerait qu'en HTML; en XHTML sans habillage de section CDATA supplémentaire, c'est toujours une erreur de bonne forme. Vous pouvez également utiliser\x3C
des attributs de gestionnaire d'événements en ligne où ils<
seraient également invalides à la fois en HTML et en XHTML, de sorte qu'il a une applicabilité plus large: si je choisissais un, un moyen facilement automatisé pour échapper des caractères sensibles dans les littéraux de chaîne JS pour tous les contextes, c'est celui que je choisirais.<
peut être utilisé dans les attributs du gestionnaire d'événements en ligne. html5.validator.nu/… Et vous avez raison sur la compatibilité XHTML d'\x3C
un sich, mais puisque XHTML ne prend pas en chargedocument.write
(ouinnerHTML
) de toute façon, je ne vois pas en quoi cela est pertinent.document.write
n'est pas pertinent, il se trouve que c'est juste l'exemple. L'OP aurait pu utiliser innerHTML, il s'agit de cacher la</
séquence de caractères à l'analyseur de balisage, où qu'elle se produise. C'est juste que la plupart des analyseurs le tolèrent dans un élément de script alors qu'ils ne le devraient pas strictement (mais les analyseurs HTML sont très tolérants). Vous avez cependant raison, cela<\/
suffit dans tous les cas pour HTML.document.write('<script src="foo.js">\x3C/script>')
semble être suffisant dans tous les navigateurs pour revenir à IE6. (J'ai omis l'attribut type car il n'est pas requis en HTML5, ni appliqué comme requis par n'importe quel navigateur.)Voici une autre variante que j'ai utilisée lorsque je voulais générer une balise de script en ligne (afin qu'elle s'exécute immédiatement) sans avoir besoin d'aucune forme d'échappement:
(Remarque: contrairement à la plupart des exemples sur le net, je ne mets
type="text/javascript"
ni la balise englobante, ni la balise générée: il n'y a pas de navigateur qui n'en a pas par défaut, et donc c'est redondant, mais ça ne fera pas de mal non plus, si vous n'êtes pas d'accord).la source
Je pense que c'est pour empêcher l'analyseur HTML du navigateur d'interpréter le <script>, et principalement le </script> comme la balise de fermeture du script réel, mais je ne pense pas que l'utilisation de document.write est une excellente idée pour évaluer le script blocs, pourquoi ne pas utiliser le DOM ...
la source
La solution proposée par Bobince fonctionne parfaitement pour moi. Je voulais aussi proposer une méthode alternative aux futurs visiteurs:
Dans cet exemple, j'ai inclus une charge conditionnelle pour jQuery pour illustrer le cas d'utilisation. J'espère que c'est utile pour quelqu'un!
la source
L'
</script>
intérieur de la chaîne Javascript littérale est interprété par l'analyseur HTML comme une balise de fermeture, provoquant un comportement inattendu ( voir l'exemple sur JSFiddle ).Pour éviter cela, vous pouvez placer votre javascript entre les commentaires (ce style de codage était une pratique courante, à l'époque où Javascript était mal pris en charge par les navigateurs). Cela fonctionnerait ( voir l'exemple dans JSFiddle ):
... mais pour être honnête, l'utilisation
document.write
n'est pas quelque chose que je considérerais comme la meilleure pratique. Pourquoi ne pas manipuler directement le DOM?la source
append
place deappendChild
. Correction de la réponse. Merci d'avoir remarqué!